<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Chapter 18 Group Replication</title>
<link rel="stylesheet" href="mvl.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets + chunker.py v1.9.2" />
<link rel="start" href="index.html" title="{book-title}" />
<link rel="up" href="" title="" />
<link rel="prev" href="replication.html" title="Chapter 17 Replication" />
<link rel="next" href="mysql-shell-userguide.html" title="Chapter 19 MySQL Shell" />
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Chapter 18 Group Replication</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="replication.html">Prev</a> </td>
<th width="60%" align="center"></th>
<td width="20%" align="right"> <a accesskey="n" href="mysql-shell-userguide.html">Next</a></td>
</tr>
</table>
<hr>
</div>
<div class="chapter">
<div class="titlepage">
<div>
<div>
<h1 class="title"><a name="group-replication"></a>Chapter 18 Group Replication</h1>

</div>

</div>

</div>
<div class="toc">
<p><b>Table of Contents</b></p><dl class="toc"><dt><span class="section"><a href="group-replication.html#group-replication-background">18.1 Group Replication Background</a></span></dt><dd><dl><dt><span class="section"><a href="group-replication.html#group-replication-replication-technologies">18.1.1 Replication Technologies</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-use-cases">18.1.2 Group Replication Use Cases</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-deploying-in-multi-primary-or-single-primary-mode">18.1.3 Multi-Primary and Single-Primary Modes</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-details">18.1.4 Group Replication Services</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-plugin-architecture">18.1.5 Group Replication Plugin Architecture</a></span></dt></dl></dd><dt><span class="section"><a href="group-replication.html#group-replication-getting-started">18.2 Getting Started</a></span></dt><dd><dl><dt><span class="section"><a href="group-replication.html#group-replication-deploying-in-single-primary-mode">18.2.1 Deploying Group Replication in Single-Primary Mode</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-deploying-locally">18.2.2 Deploying Group Replication Locally</a></span></dt></dl></dd><dt><span class="section"><a href="group-replication.html#group-replication-monitoring">18.3 Monitoring Group Replication</a></span></dt><dd><dl><dt><span class="section"><a href="group-replication.html#group-replication-server-states">18.3.1 Group Replication Server States</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-replication-group-members">18.3.2 The replication_group_members Table</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-replication-group-member-stats">18.3.3 The replication_group_member_stats Table</a></span></dt></dl></dd><dt><span class="section"><a href="group-replication.html#group-replication-operations">18.4 Group Replication Operations</a></span></dt><dd><dl><dt><span class="section"><a href="group-replication.html#group-replication-configuring-online-group">18.4.1 Configuring an Online Group</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-consistency-guarantees">18.4.2 Transaction Consistency Guarantees</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-distributed-recovery">18.4.3 Distributed Recovery</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-network-partitioning">18.4.4 Network Partitioning</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-ipv6">18.4.5 Support For IPv6 And For Mixed IPv6 And IPv4 Groups</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-enterprise-backup">18.4.6 Using MySQL Enterprise Backup with Group Replication</a></span></dt></dl></dd><dt><span class="section"><a href="group-replication.html#group-replication-security">18.5 Group Replication Security</a></span></dt><dd><dl><dt><span class="section"><a href="group-replication.html#group-replication-ip-address-whitelisting">18.5.1 Group Replication IP Address Whitelisting</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-secure-socket-layer-support-ssl">18.5.2 Group Replication Secure Socket Layer (SSL) Support</a></span></dt></dl></dd><dt><span class="section"><a href="group-replication.html#group-replication-performance">18.6 Group Replication Performance</a></span></dt><dd><dl><dt><span class="section"><a href="group-replication.html#group-replication-fine-tuning-the-group-communication-thread">18.6.1 Fine Tuning the Group Communication Thread</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-flow-control">18.6.2 Flow Control</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-message-compression">18.6.3 Message Compression</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-performance-message-fragmentation">18.6.4 Message Fragmentation</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-performance-xcom-cache">18.6.5 XCom Cache Management</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-responses-failure">18.6.6 Responses to Failure Detection and Network Partitioning</a></span></dt></dl></dd><dt><span class="section"><a href="group-replication.html#group-replication-upgrade">18.7 Upgrading Group Replication</a></span></dt><dd><dl><dt><span class="section"><a href="group-replication.html#group-replication-online-upgrade-combining-versions">18.7.1 Combining Different Member Versions in a Group</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-offline-upgrade">18.7.2 Group Replication Offline Upgrade</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-online-upgrade">18.7.3 Group Replication Online Upgrade</a></span></dt></dl></dd><dt><span class="section"><a href="group-replication.html#group-replication-options">18.8 Group Replication System Variables</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-requirements-and-limitations">18.9 Requirements and Limitations</a></span></dt><dd><dl><dt><span class="section"><a href="group-replication.html#group-replication-requirements">18.9.1 Group Replication Requirements</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-limitations">18.9.2 Group Replication Limitations</a></span></dt></dl></dd><dt><span class="section"><a href="group-replication.html#group-replication-frequently-asked-questions">18.10 Frequently Asked Questions</a></span></dt></dl>
</div>
<a class="indexterm" name="idm46444260495040"></a><a class="indexterm" name="idm46444260493968"></a><p>
    This chapter explains MySQL Group Replication and how to install,
    configure and monitor groups. MySQL Group Replication is a MySQL
    Server plugin that enables you to create elastic, highly-available,
    fault-tolerant replication topologies.
  </p><p>
    Groups can operate in a single-primary mode with automatic primary
    election, where only one server accepts updates at a time.
    Alternatively, for more advanced users, groups can be deployed in
    multi-primary mode, where all servers can accept updates, even if
    they are issued concurrently.
  </p><p>
    There is a built-in group membership service that keeps the view of
    the group consistent and available for all servers at any given
    point in time. Servers can leave and join the group and the view is
    updated accordingly. Sometimes servers can leave the group
    unexpectedly, in which case the failure detection mechanism detects
    this and notifies the group that the view has changed. This is all
    automatic.
  </p><p>
    The chapter is structured as follows:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
        <a class="xref" href="group-replication.html#group-replication-background" title="18.1 Group Replication Background">Section 18.1, “Group Replication Background”</a> provides an
        introduction to groups and how Group Replication works.
      </p></li><li class="listitem"><p>
        <a class="xref" href="group-replication.html#group-replication-getting-started" title="18.2 Getting Started">Section 18.2, “Getting Started”</a> explains how
        to configure multiple MySQL Server instances to create a group.
      </p></li><li class="listitem"><p>
        <a class="xref" href="group-replication.html#group-replication-monitoring" title="18.3 Monitoring Group Replication">Section 18.3, “Monitoring Group Replication”</a> explains how to
        monitor a group.
      </p></li><li class="listitem"><p>
        <a class="xref" href="group-replication.html#group-replication-operations" title="18.4 Group Replication Operations">Section 18.4, “Group Replication Operations”</a> explains how to
        work with a group.
      </p></li><li class="listitem"><p>
        <a class="xref" href="group-replication.html#group-replication-security" title="18.5 Group Replication Security">Section 18.5, “Group Replication Security”</a> explains how to
        secure a group.
      </p></li><li class="listitem"><p>
        <a class="xref" href="group-replication.html#group-replication-performance" title="18.6 Group Replication Performance">Section 18.6, “Group Replication Performance”</a> explains how to
        fine tune performance for a group.
      </p></li><li class="listitem"><p>
        <a class="xref" href="group-replication.html#group-replication-upgrade" title="18.7 Upgrading Group Replication">Section 18.7, “Upgrading Group Replication”</a> explains how to
        upgrade a group.
      </p></li><li class="listitem"><p>
        <a class="xref" href="group-replication.html#group-replication-options" title="18.8 Group Replication System Variables">Section 18.8, “Group Replication System Variables”</a> is a reference for
        the system variables specific to Group Replication.
      </p></li><li class="listitem"><p>
        <a class="xref" href="group-replication.html#group-replication-requirements-and-limitations" title="18.9 Requirements and Limitations">Section 18.9, “Requirements and Limitations”</a>
        explains technical requirements and limitations for Group
        Replication.
      </p></li><li class="listitem"><p>
        <a class="xref" href="group-replication.html#group-replication-frequently-asked-questions" title="18.10 Frequently Asked Questions">Section 18.10, “Frequently Asked Questions”</a>
        provides answers to some technical questions about deploying and
        operating Group Replication.
</p></li></ul>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a name="group-replication-background"></a>18.1 Group Replication Background</h2>

</div>

</div>

</div>
<div class="toc">
<dl class="toc"><dt><span class="section"><a href="group-replication.html#group-replication-replication-technologies">18.1.1 Replication Technologies</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-use-cases">18.1.2 Group Replication Use Cases</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-deploying-in-multi-primary-or-single-primary-mode">18.1.3 Multi-Primary and Single-Primary Modes</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-details">18.1.4 Group Replication Services</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-plugin-architecture">18.1.5 Group Replication Plugin Architecture</a></span></dt></dl>
</div>
<a class="indexterm" name="idm46444260471120"></a><p>
    This section provides background information on MySQL Group
    Replication.

    
  </p><p>
    The most common way to create a fault-tolerant system is to resort
    to making components redundant, in other words the component can be
    removed and the system should continue to operate as expected. This
    creates a set of challenges that raise complexity of such systems to
    a whole different level. Specifically, replicated databases have to
    deal with the fact that they require maintenance and administration
    of several servers instead of just one. Moreover, as servers are
    cooperating together to create the group several other classic
    distributed systems problems have to be dealt with, such as network
    partitioning or split brain scenarios.
  </p><p>
    Therefore, the ultimate challenge is to fuse the logic of the
    database and data replication with the logic of having several
    servers coordinated in a consistent and simple way. In other words,
    to have multiple servers agreeing on the state of the system and the
    data on each and every change that the system goes through. This can
    be summarized as having servers reaching agreement on each database
    state transition, so that they all progress as one single database
    or alternatively that they eventually converge to the same state.
    Meaning that they need to operate as a (distributed) state machine.
  </p><p>
    MySQL Group Replication provides distributed state machine
    replication with strong coordination between servers. Servers
    coordinate themselves automatically when they are part of the same
    group. The group can operate in a single-primary mode with automatic
    primary election, where only one server accepts updates at a time.
    Alternatively, for more advanced users the group can be deployed in
    multi-primary mode, where all servers can accept updates, even if
    they are issued concurrently. This power comes at the expense of
    applications having to work around the limitations imposed by such
    deployments.
  </p><p>
    There is a built-in group membership service that keeps the view of
    the group consistent and available for all servers at any given
    point in time. Servers can leave and join the group and the view is
    updated accordingly. Sometimes servers can leave the group
    unexpectedly, in which case the failure detection mechanism detects
    this and notifies the group that the view has changed. This is all
    automatic.
  </p><p>
    For a transaction to commit, the majority of the group have to agree
    on the order of a given transaction in the global sequence of
    transactions. Deciding to commit or abort a transaction is done by
    each server individually, but all servers make the same decision. If
    there is a network partition, resulting in a split where members are
    unable to reach agreement, then the system does not progress until
    this issue is resolved. Hence there is also a built-in, automatic,
    split-brain protection mechanism.
  </p><p>
    All of this is powered by the provided Group Communication System
    (GCS) protocols. These provide a failure detection mechanism, a
    group membership service, and safe and completely ordered message
    delivery. All these properties are key to creating a system which
    ensures that data is consistently replicated across the group of
    servers. At the very core of this technology lies an implementation
    of the Paxos algorithm. It acts as the group communication engine.
</p>
<div class="section">

<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="group-replication-replication-technologies"></a>18.1.1 Replication Technologies</h3>

</div>

</div>

</div>

<div class="toc">
<dl class="toc"><dt><span class="section"><a href="group-replication.html#group-replication-primary-secondary-replication">18.1.1.1 Primary-Secondary Replication</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-summary">18.1.1.2 Group Replication</a></span></dt></dl>
</div>
<a class="indexterm" name="idm46444260461328"></a><a class="indexterm" name="idm46444260459824"></a><p>
      Before getting into the details of MySQL Group Replication, this
      section introduces some background concepts and an overview of how
      things work. This provides some context to help understand what is
      required for Group Replication and what the differences are
      between classic asynchronous MySQL Replication and Group
      Replication.
</p>
<div class="section">

<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="group-replication-primary-secondary-replication"></a>18.1.1.1 Primary-Secondary Replication</h4>
</div>
</div>
</div>
<a class="indexterm" name="idm46444260456800"></a><a class="indexterm" name="idm46444260455296"></a><p>
        Traditional MySQL Replication provides a simple
        Primary-Secondary approach to replication. There is a primary
        (master) and there is one or more secondaries (slaves). The
        primary executes transactions, commits them and then they are
        later (thus asynchronously) sent to the secondaries to be either
        re-executed (in statement-based replication) or applied (in
        row-based replication). It is a shared-nothing system, where all
        servers have a full copy of the data by default.
</p>
<div class="figure">
<a name="idm46444260452848"></a><p class="title"><b>Figure 18.1 MySQL Asynchronous Replication</b></p>
<div class="figure-contents">

<div class="mediaobject">
<img src="images/async-replication-diagram.png" width="911" height="315" alt="A transaction received by the master is executed, written to the binary log, then committed, and a response is sent to the client application. The record from the binary log is sent to the relay logs on Slave 1 and Slave 2 before the commit takes place on the master. On each of the slaves, the transaction is applied, written to the slave's binary log, and committed. The commit on the master and the commits on the slaves are all independent and asynchronous.">
</div>

</div>

</div>
<br class="figure-break"><p>
        There is also semisynchronous replication, which adds one
        synchronization step to the protocol. This means that the
        Primary waits, at commit time, for the secondary to acknowledge
        that it has <span class="emphasis"><em>received</em></span> the transaction. Only
        then does the Primary resume the commit operation.
</p>
<div class="figure">
<a name="idm46444260444560"></a><p class="title"><b>Figure 18.2 MySQL Semisynchronous Replication</b></p>
<div class="figure-contents">

<div class="mediaobject">
<img src="images/semisync-replication-diagram.png" width="911" height="316" alt="A transaction received by the master is executed and written to the binary log. The record from the binary log is sent to the relay logs on Slave 1 and Slave 2. The master then waits for an acknowledgement from the slaves. When both of the slaves have returned the acknowledgement, the master commits the transaction, and a response is sent to the client application. After each slave has returned its acknowlegement, it applies the transaction, writes it to the binary log, and commits it. The commit on the master depends on the acknowledgement from the slaves, but the commits on the slaves are independent from each other and from the commit on the master.">
</div>

</div>

</div>
<br class="figure-break"><p>
        In the two pictures above, you can see a diagram of the classic
        asynchronous MySQL Replication protocol (and its semisynchronous
        variant as well). Diagonal arrows represent messages exchanged
        between servers or messages exchanged between servers and the
        client application.
</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="group-replication-summary"></a>18.1.1.2 Group Replication</h4>

</div>

</div>

</div>
<a class="indexterm" name="idm46444260435152"></a><p>
        Group Replication is a technique that can be used to implement
        fault-tolerant systems. The replication group is a set of
        servers that each have their own entire copy of the data (a
        shared-nothing replication scheme), and interact with each other
        through message passing. The communication layer provides a set
        of guarantees such as atomic message and total order message
        delivery. These are very powerful properties that translate into
        very useful abstractions that one can resort to build more
        advanced database replication solutions.
      </p><p>
        MySQL Group Replication builds on top of such properties and
        abstractions and implements a multi-master update everywhere
        replication protocol. A replication group is formed by multiple
        servers and each server in the group may execute transactions
        independently at any time. However, all read-write transactions
        commit only after they have been approved by the group. In other
        words, for any read-write transaction the group needs to decide
        whether it commits or not, so the commit operation is not a
        unilateral decision from the originating server. Read-only
        transactions need no coordination within the group and commit
        immediately.
      </p><p>
        When a read-write transaction is ready to commit at the
        originating server, the server atomically broadcasts the write
        values (the rows that were changed) and the corresponding write
        set (the unique identifiers of the rows that were updated).
        Because the transaction is sent through an atomic broadcast,
        either all servers in the group receive the transaction or none
        do. If they receive it, then they all receive it in the same
        order with respect to other transactions that were sent before.
        All servers therefore receive the same set of transactions in
        the same order, and a global total order is established for the
        transactions.
      </p><p>
        However, there may be conflicts between transactions that
        execute concurrently on different servers. Such conflicts are
        detected by inspecting and comparing the write sets of two
        different and concurrent transactions, in a process called
        <span class="emphasis"><em>certification</em></span>. During certification,
        conflict detection is carried out at row level: if two
        concurrent transactions, that executed on different servers,
        update the same row, then there is a conflict. The conflict
        resolution procedure states that the transaction that was
        ordered first commits on all servers, and the transaction
        ordered second aborts, and is therefore rolled back on the
        originating server and dropped by the other servers in the
        group. For example, if t1 and t2 execute concurrently at
        different sites, both changing the same row, and t2 is ordered
        before t1, then t2 wins the conflict and t1 is rolled back. This
        is in fact a distributed first commit wins rule. Note that if
        two transactions are bound to conflict more often than not, then
        it is a good practice to start them on the same server, where
        they have a chance to synchronize on the local lock manager
        instead of being rolled back as a result of certification.
      </p><p>
        For applying and externalizing the certified transactions, Group
        Replication permits servers to deviate from the agreed order of
        the transactions if this does not break consistency and
        validity. Group Replication is an eventual consistency system,
        meaning that as soon as the incoming traffic slows down or
        stops, all group members have the same data content. While
        traffic is flowing, transactions can be externalized in a
        slightly different order, or externalized on some members before
        the others. For example, in multi-primary mode, a local
        transaction might be externalized immediately following
        certification, although a remote transaction that is earlier in
        the global order has not yet been applied. This is permitted
        when the certification process has established that there is no
        conflict between the transactions. In single-primary mode, on
        the primary server, there is a small chance that concurrent,
        non-conflicting local transactions might be committed and
        externalized in a different order from the global order agreed
        by Group Replication. On the secondaries, which do not accept
        writes from clients, transactions are always committed and
        externalized in the agreed order.
      </p><p>
        The following figure depicts the MySQL Group Replication
        protocol and by comparing it to MySQL Replication (or even MySQL
        semisynchronous replication) you can see some differences. Some
        underlying consensus and Paxos related messages are missing from
        this picture for the sake of clarity.
</p>
<div class="figure">
<a name="idm46444260424368"></a><p class="title"><b>Figure 18.3 MySQL Group Replication Protocol</b></p>
<div class="figure-contents">

<div class="mediaobject">
<img src="images/gr-replication-diagram.png" width="898" height="375" alt="A transaction received by Master 1 is executed. Master 1 then sends a message to the replication group, consisting of itself, Master 2, and Master 3. When all three members have reached consensus, they certify the transaction. Master 1 then writes the transaction to its binary log, commits it, and sends a response to the client application. Masters 2 and 3 write the transaction to their relay logs, then apply it, write it to the binary log, and commit it.">
</div>

</div>

</div>
<br class="figure-break">
</div>

</div>

<div class="section">

<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="group-replication-use-cases"></a>18.1.2 Group Replication Use Cases</h3>

</div>

</div>

</div>

<div class="toc">
<dl class="toc"><dt><span class="section"><a href="group-replication.html#group-replication-examples-of-use-case-scenarios">18.1.2.1 Examples of Use Case Scenarios</a></span></dt></dl>
</div>
<a class="indexterm" name="idm46444260415824"></a><p>
      Group Replication enables you to create fault-tolerant systems
      with redundancy by replicating the system state to a set of
      servers. Even if some of the servers subsequently fail, as long it
      is not all or a majority, the system is still available. Depending
      on the number of servers which fail the group might have degraded
      performance or scalability, but it is still available. Server
      failures are isolated and independent. They are tracked by a group
      membership service which relies on a distributed failure detector
      that is able to signal when any servers leave the group, either
      voluntarily or due to an unexpected halt. There is a distributed
      recovery procedure to ensure that when servers join the group they
      are brought up to date automatically. There is no need for server
      failover, and the multi-master update everywhere nature ensures
      that even updates are not blocked in the event of a single server
      failure. To summarize, MySQL Group Replication guarantees that the
      database service is continuously available.
    </p><p>
      It is important to understand that although the database service
      is available, in the event of a server crash, those clients
      connected to it must be redirected, or failed over, to a different
      server. This is not something Group Replication attempts to
      resolve. A connector, load balancer, router, or some form of
      middleware are more suitable to deal with this issue. For example
      see <a class="ulink" href="https://dev.mysql.com/doc/mysql-router/8.0/en/" target="_top">MySQL Router 8.0</a>.
    </p><p>
      To summarize, MySQL Group Replication provides a highly available,
      highly elastic, dependable MySQL service.
</p>
<div class="section">

<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="group-replication-examples-of-use-case-scenarios"></a>18.1.2.1 Examples of Use Case Scenarios</h4>
</div>
</div>
</div>
<a class="indexterm" name="idm46444260409472"></a><p>
        The following examples are typical use cases for Group
        Replication.
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            <span class="emphasis"><em>Elastic Replication</em></span> - Environments that
            require a very fluid replication infrastructure, where the
            number of servers has to grow or shrink dynamically and with
            as few side-effects as possible. For instance, database
            services for the cloud.
          </p></li><li class="listitem"><p>
            <span class="emphasis"><em>Highly Available Shards</em></span> - Sharding is a
            popular approach to achieve write scale-out. Use MySQL Group
            Replication to implement highly available shards, where each
            shard maps to a replication group.
          </p></li><li class="listitem"><p>
            <span class="emphasis"><em>Alternative to Master-Slave replication</em></span>
            - In certain situations, using a single master server makes
            it a single point of contention. Writing to an entire group
            may prove more scalable under certain circumstances.

            
          </p></li><li class="listitem"><p>
            <span class="emphasis"><em>Autonomic Systems</em></span> - Additionally, you
            can deploy MySQL Group Replication purely for the automation
            that is built into the replication protocol (described
            already in this and previous chapters).

            
</p></li></ul>
</div>

</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="group-replication-deploying-in-multi-primary-or-single-primary-mode"></a>18.1.3 Multi-Primary and Single-Primary Modes</h3>

</div>

</div>

</div>
<div class="toc">
<dl class="toc"><dt><span class="section"><a href="group-replication.html#group-replication-single-primary-mode">18.1.3.1 Single-Primary Mode</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-multi-primary-mode">18.1.3.2 Multi-Primary Mode</a></span></dt></dl>
</div>
<a class="indexterm" name="idm46444260398288"></a><a class="indexterm" name="idm46444260396784"></a><a class="indexterm" name="idm46444260395296"></a><p>
      Group Replication operates either in single-primary mode or in
      multi-primary mode. The group's mode is a group-wide configuration
      setting, specified by the
      <a class="link" href="group-replication.html#sysvar_group_replication_single_primary_mode"><code class="literal">group_replication_single_primary_mode</code></a>
      system variable, which must be the same on all members.
      <code class="literal">ON</code> means single-primary mode, which is the
      default mode, and <code class="literal">OFF</code> means multi-primary mode.
      It is not possible to have members of the group deployed in
      different modes, for example one member configured in
      multi-primary mode while another member is in single-primary mode.
    </p><p>
      You cannot change the value of
      <a class="link" href="group-replication.html#sysvar_group_replication_single_primary_mode"><code class="literal">group_replication_single_primary_mode</code></a>
      manually while Group Replication is running. From MySQL 8.0.13,
      you can use the
      <a class="link" href="sql-statements.html#udf_group-replication-switch-to-single-primary-mode"><code class="literal">group_replication_switch_to_single_primary_mode()</code></a>
      and
      <a class="link" href="sql-statements.html#udf_group-replication-switch-to-multi-primary-mode"><code class="literal">group_replication_switch_to_multi_primary_mode()</code></a>
      UDFs to move a group from one mode to another while Group
      Replication is still running. These UDFs manage the process of
      changing the group's mode and ensure the safety and consistency of
      your data. In earlier releases, to change the group's mode you
      must stop Group Replication and change the value of
      <a class="link" href="group-replication.html#sysvar_group_replication_single_primary_mode"><code class="literal">group_replication_single_primary_mode</code></a>
      on all members. Then carry out a full reboot of the group (a
      bootstrap by a server with
      <a class="link" href="group-replication.html#sysvar_group_replication_bootstrap_group"><code class="literal">group_replication_bootstrap_group=ON</code></a>)
      to implement the change to the new operating configuration. You do
      not need to restart the servers.
    </p><p>
      Regardless of the deployed mode, Group Replication does not handle
      client-side failover. That must be handled by a middleware
      framework such as <a class="ulink" href="https://dev.mysql.com/doc/mysql-router/8.0/en/" target="_top">MySQL Router 8.0</a>, a proxy, a
      connector, or the application itself.
</p>
<div class="section">

<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="group-replication-single-primary-mode"></a>18.1.3.1 Single-Primary Mode</h4>
</div>
</div>
</div>
<a class="indexterm" name="idm46444260380208"></a><a class="indexterm" name="idm46444260378720"></a><p>
        In single-primary mode
        (<a class="link" href="group-replication.html#sysvar_group_replication_single_primary_mode"><code class="literal">group_replication_single_primary_mode=ON</code></a>)
        the group has a single primary server that is set to read-write
        mode. All the other members in the group are set to read-only
        mode (with <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super-read-only=ON</code></a>).
        The primary is typically the first server to bootstrap the
        group. All other servers that join the group learn about the
        primary server and are automatically set to read-only mode.
      </p><p>
        In single-primary mode, Group Replication enforces that only a
        single server writes to the group, so compared to multi-primary
        mode, consistency checking can be less strict and DDL statements
        do not need to be handled with any extra care. The option
        <a class="link" href="group-replication.html#sysvar_group_replication_enforce_update_everywhere_checks"><code class="literal">group_replication_enforce_update_everywhere_checks</code></a>
        enables or disables strict consistency checks for a group. When
        deploying in single-primary mode, or changing the group to
        single-primary mode, this system variable must be set to
        <code class="literal">OFF</code>.
      </p><p>
        The member that is designated as the primary server can change
        in the following ways:

</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              If the existing primary leaves the group, whether
              voluntarily or unexpectedly, a new primary is elected
              automatically.
            </p></li><li class="listitem"><p>
              You can appoint a specific member as the new primary using
              the
              <a class="link" href="sql-statements.html#udf_group-replication-set-as-primary"><code class="literal">group_replication_set_as_primary()</code></a>
              UDF.
            </p></li><li class="listitem"><p>
              If you use the
              <a class="link" href="sql-statements.html#udf_group-replication-switch-to-single-primary-mode"><code class="literal">group_replication_switch_to_single_primary_mode()</code></a>
              UDF to change a group that was running in multi-primary
              mode to run in single-primary mode, a new primary is
              elected automatically, or you can appoint the new primary
              by specifying it with the UDF.
</p></li></ul>
</div>
<p>

        The UDFs can only be used when all group members are running
        MySQL 8.0.13 or higher. When a new primary server is elected
        automatically or appointed manually, it is automatically set to
        read-write, and the other group members remain as secondaries,
        and as such, read-only.
        <a class="xref" href="group-replication.html#group-replication-primary-election-diagram" title="Figure 18.4 New Primary Election">Figure 18.4, “New Primary Election”</a>
        shows this process.
</p>
<div class="figure">
<a name="group-replication-primary-election-diagram"></a><p class="title"><b>Figure 18.4 New Primary Election</b></p>
<div class="figure-contents">

<div class="mediaobject">
<img src="images/single-primary-election.png" width="948" height="327" alt="Five server instances, S1, S2, S3, S4, and S5, are deployed as an interconnected group. Server S1 is the primary. Write clients are communicating with server S1, and a read client is communicating with server S4. Server S1 then fails, breaking communication with the write clients. Server S2 then takes over as the new primary, and the write clients now communicate with server S2.">
</div>

</div>

</div>
<br class="figure-break"><p>
        When a new primary is elected or appointed, it might have a
        backlog of changes that had been applied on the old primary but
        have not yet been applied on this server. In this situation,
        until the new primary catches up with the old primary,
        read-write transactions might result in conflicts and be rolled
        back, and read-only transactions might result in stale reads.
        Group Replication's flow control mechanism, which minimizes the
        difference between fast and slow members, reduces the chances of
        this happening if it is activated and properly tuned. For more
        information on flow control, see
        <a class="xref" href="group-replication.html#group-replication-flow-control" title="18.6.2 Flow Control">Section 18.6.2, “Flow Control”</a>. From MySQL
        8.0.14, you can also use the
        <a class="link" href="group-replication.html#sysvar_group_replication_consistency"><code class="literal">group_replication_consistency</code></a>
        system variable to configure the group's level of transaction
        consistency to prevent this issue. The setting
        <code class="literal">BEFORE_ON_PRIMARY_FAILOVER</code> (or any higher
        consistency level) holds new transactions on a newly elected
        primary until the backlog has been applied. For more information
        on transaction consistency, see
        <a class="xref" href="group-replication.html#group-replication-consistency-guarantees" title="18.4.2 Transaction Consistency Guarantees">Section 18.4.2, “Transaction Consistency Guarantees”</a>. If
        flow control and transaction consistency guarantees are not used
        for a group, it is a good practice to wait for the new primary
        to apply its replication-related relay log before re-routing
        client applications to it.
</p>
<div class="section">

<div class="titlepage">
<div>
<div>
<h5 class="title"><a name="group-replication-primary-election"></a>18.1.3.1.1 Primary Election Algorithm</h5>
</div>
</div>
</div>
<p>
          The automatic primary member election process involves each
          member looking at the new view of the group, ordering the
          potential new primary members, and choosing the member that
          qualifies as the most suitable. Each member makes its own
          decision locally, following the primary election algorithm in
          its MySQL Server release. Because all members must reach the
          same decision, members adapt their primary election algorithm
          if other group members are running lower MySQL Server
          versions, so that they have the same behavior as the member
          with the lowest MySQL Server version in the group.
        </p><p>
          The factors considered by members when electing a primary, in
          order, are as follows:

</p>
<div class="orderedlist">
<ol class="orderedlist" type="1"><li class="listitem"><p>
                The first factor considered is which member or members
                are running the lowest MySQL Server version. If all
                group members are running MySQL 8.0.17 or higher,
                members are first ordered by the patch version of their
                release. If any members are running MySQL Server 5.7 or
                MySQL 8.0.16 or lower, members are first ordered by the
                major version of their release, and the patch version is
                ignored.
              </p></li><li class="listitem"><p>
                If more than one member is running the lowest MySQL
                Server version, the second factor considered is the
                member weight of each of those members, as specified by
                the
                <a class="link" href="group-replication.html#sysvar_group_replication_member_weight"><code class="literal">group_replication_member_weight</code></a>
                system variable on the member. If any member of the
                group is running MySQL Server 5.7, where this system
                variable was not available, this factor is ignored.
              </p><p>
                The
                <a class="link" href="group-replication.html#sysvar_group_replication_member_weight"><code class="literal">group_replication_member_weight</code></a>
                system variable specifies a number in the range 0-100.
                All members default to a weight of 50, so set a weight
                below this to lower their ordering, and a weight above
                it to increase their ordering. You can use this
                weighting function to prioritize the use of better
                hardware or to ensure failover to a specific member
                during scheduled maintenance of the primary.
              </p></li><li class="listitem"><p>
                If more than one member is running the lowest MySQL
                Server version, and more than one of those members has
                the highest member weight (or member weighting is being
                ignored), the third factor considered is the
                lexographical order of the generated server UUIDs of
                each member, as specified by the
                <a class="link" href="replication.html#sysvar_server_uuid"><code class="literal">server_uuid</code></a> system
                variable. The member with the lowest server UUID is
                chosen as the primary. This factor acts as a guaranteed
                and predictable tie-breaker so that all group members
                reach the same decision if it cannot be determined by
                any important factors.
</p></li></ol>
</div>
<p>
</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h5 class="title"><a name="group-replication-find-primary"></a>18.1.3.1.2 Finding the Primary</h5>

</div>

</div>

</div>
<a class="indexterm" name="idm46444260336336"></a><p>
          To find out which server is currently the primary when
          deployed in single-primary mode, use the
          <code class="literal">MEMBER_ROLE</code> column in the
          <a class="link" href="performance-schema.html#replication-group-members-table" title="26.12.11.9 The replication_group_members Table"><code class="literal">performance_schema.replication_group_members</code></a>
          table. For example:
        </p><pre data-lang="sql" class="programlisting">mysql&gt; <strong class="userinput"><code>SELECT MEMBER_HOST, MEMBER_ROLE FROM performance_schema.replication_group_members;</code></strong>
+-------------------------+-------------+
| MEMBER_HOST             | MEMBER_ROLE |
+-------------------------+-------------+
| remote1.example.com     | PRIMARY     |
| remote2.example.com     | SECONDARY   |
| remote3.example.com     | SECONDARY   |
+-------------------------+-------------+
</pre>
<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Warning
</div>
<p>
            The <code class="literal">group_replication_primary_member</code>
            status variable has been deprecated and is scheduled to be
            removed in a future version.
</p>
</div>
<p>
          Alternatively use the
          <a class="link" href="server-administration.html#statvar_group_replication_primary_member"><code class="literal">group_replication_primary_member</code></a>
          status variable.
        </p><pre data-lang="sql" class="programlisting">mysql&gt; <strong class="userinput"><code>SHOW STATUS LIKE 'group_replication_primary_member'</code></strong>
</pre>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="group-replication-multi-primary-mode"></a>18.1.3.2 Multi-Primary Mode</h4>

</div>

</div>

</div>
<a class="indexterm" name="idm46444260323600"></a><p>
        In multi-primary mode
        (<a class="link" href="group-replication.html#sysvar_group_replication_single_primary_mode"><code class="literal">group_replication_single_primary_mode=OFF</code></a>)
        no member has a special role. Any member that is compatible with
        the other group members is set to read-write mode when joining
        the group, and can process write transactions, even if they are
        issued concurrently.
      </p><p>
        If a member stops accepting write transactions, for example in
        the event of a server crash, clients connected to it can be
        redirected, or failed over, to any other member that is in
        read-write mode. Group Replication does not handle client-side
        failover itself, so you need to arrange this using a middleware
        framework such as <a class="ulink" href="https://dev.mysql.com/doc/mysql-router/8.0/en/" target="_top">MySQL Router 8.0</a>, a proxy, a
        connector, or the application itself.
        <a class="xref" href="group-replication.html#group-replication-multi-primary-diagram" title="Figure 18.5 Client Failover">Figure 18.5, “Client Failover”</a> shows
        how clients can reconnect to an alternative group member if a
        member leaves the group.
</p>
<div class="figure">
<a name="group-replication-multi-primary-diagram"></a><p class="title"><b>Figure 18.5 Client Failover</b></p>
<div class="figure-contents">

<div class="mediaobject">
<img src="images/multi-primary.png" width="948" height="327" alt="Five server instances, S1, S2, S3, S4, and S5, are deployed as an interconnected group. All of the servers are primaries. Write clients are communicating with servers S1 and S2, and a read client is communicating with server S4. Server S1 then fails, breaking communication with its write client. This client reconnects to server S3.">
</div>

</div>

</div>
<br class="figure-break"><p>
        Group Replication is an eventual consistency system. This means
        that as soon as the incoming traffic slows down or stops, all
        group members have the same data content. While traffic is
        flowing, transactions can be externalized on some members before
        the others, especially if some members have less write
        throughput than others, creating the possibility of stale reads.
        In multi-primary mode, slower members can also build up an
        excessive backlog of transactions to certify and apply, leading
        to a greater risk of conflicts and certification failure. To
        limit these issues, you can activate and tune Group
        Replication's flow control mechanism to minimize the difference
        between fast and slow members. For more information on flow
        control, see <a class="xref" href="group-replication.html#group-replication-flow-control" title="18.6.2 Flow Control">Section 18.6.2, “Flow Control”</a>.
      </p><p>
        From MySQL 8.0.14, if you want to have a transaction consistency
        guarantee for every transaction in the group, you can do this
        using the
        <a class="link" href="group-replication.html#sysvar_group_replication_consistency"><code class="literal">group_replication_consistency</code></a>
        system variable. You can choose a setting that suits the
        workload of your group and your priorities for data reads and
        writes, taking into account the performance impact of the
        synchronization required to increase consistency. You can also
        set the system variable for individual sessions to protect
        particularly concurrency-sensitive transactions. For more
        information on transaction consistency, see
        <a class="xref" href="group-replication.html#group-replication-consistency-guarantees" title="18.4.2 Transaction Consistency Guarantees">Section 18.4.2, “Transaction Consistency Guarantees”</a>.
</p>
<div class="section">

<div class="titlepage">
<div>
<div>
<h5 class="title"><a name="group-replication-multi-primary-checks"></a>18.1.3.2.1 Transaction Checks</h5>
</div>
</div>
</div>
<p>
          When a group is deployed in multi-primary mode, transactions
          are checked to ensure they are compatible with the mode. The
          following strict consistency checks are made when Group
          Replication is deployed in multi-primary mode:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              If a transaction is executed under the SERIALIZABLE
              isolation level, then its commit fails when synchronizing
              itself with the group.
            </p></li><li class="listitem"><p>
              If a transaction executes against a table that has foreign
              keys with cascading constraints, then its commit fails
              when synchronizing itself with the group.
</p></li></ul>
</div>
<p>
          The checks are controlled by the
          <a class="link" href="group-replication.html#sysvar_group_replication_enforce_update_everywhere_checks"><code class="literal">group_replication_enforce_update_everywhere_checks</code></a>
          system variable. In multi-primary mode, the system variable
          should normally be set to <code class="literal">ON</code>, but the
          checks can optionally be deactivated by setting the system
          variable to <code class="literal">OFF</code>. When deploying in
          single-primary mode, the system variable must be set to
          <code class="literal">OFF</code>.
</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h5 class="title"><a name="group-replication-data-definition-statements"></a>18.1.3.2.2 Data Definition Statements</h5>

</div>

</div>

</div>
<a class="indexterm" name="idm46444260295216"></a><p>
          In a Group Replication topology in multi-primary mode, care
          needs to be taken when executing data definition statements,
          also commonly known as data definition language (DDL).
        </p><p>
          MySQL 8.0 introduces support for atomic Data Definition
          Language (DDL) statements, where the complete DDL statement is
          either committed or rolled back as a single atomic
          transaction. However, DDL statements, atomic or otherwise,
          implicitly end any transaction that is active in the current
          session, as if you had done a
          <a class="link" href="sql-statements.html#commit" title="13.3.1 START TRANSACTION, COMMIT, and ROLLBACK Statements"><code class="literal">COMMIT</code></a> before executing the
          statement. This means that DDL statements cannot be performed
          within another transaction, within transaction control
          statements such as
          <a class="link" href="sql-statements.html#commit" title="13.3.1 START TRANSACTION, COMMIT, and ROLLBACK Statements"><code class="literal">START TRANSACTION ...
          COMMIT</code></a>, or combined with other statements within the
          same transaction.
        </p><p>
          Group Replication is based on an optimistic replication
          paradigm, where statements are optimistically executed and
          rolled back later if necessary. Each server executes without
          securing group agreement first. Therefore, more care needs to
          be taken when replicating DDL statements in multi-primary
          mode. If you make schema changes (using DDL) and changes to
          the data that an object contains (using DML) for the same
          object, the changes need to be handled through the same server
          while the schema operation has not yet completed and
          replicated everywhere. Failure to do so can result in data
          inconsistency when operations are interrupted or only
          partially completed. If the group is deployed in
          single-primary mode this issue does not occur, because all
          changes are performed through the same server, the primary.
        </p><p>
          For details on atomic DDL support in MySQL 8.0, and the
          resulting changes in behavior for the replication of certain
          statements, see <a class="xref" href="sql-statements.html#atomic-ddl" title="13.1.1 Atomic Data Definition Statement Support">Section 13.1.1, “Atomic Data Definition Statement Support”</a>.
</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h5 class="title"><a name="group-replication-multi-primary-compatibility"></a>18.1.3.2.3 Version Compatibility</h5>

</div>

</div>

</div>
<p>
          For optimal compatibility and performance, all members of a
          group should run the same version of MySQL Server and
          therefore of Group Replication. In multi-primary mode, this is
          more significant because all members would normally join the
          group in read-write mode. If a group includes members running
          more than one MySQL Server version, there is a potential for
          some members to be incompatible with others, because they
          support functions others do not, or lack functions others
          have. To guard against this, when a new member joins
          (including a former member that has been upgraded and
          restarted), the member carries out compatibility checks
          against the rest of the group.
        </p><p>
          One result of these compatibility checks is particularly
          important in multi-primary mode. If a joining member is
          running a higher MySQL Server version than the lowest version
          that the existing group members are running, it joins the
          group but remains in read-only mode. (In a group that is
          running in single-primary mode, newly added members default to
          being read-only in any case.) Members running MySQL 8.0.17 or
          higher take into account the patch version of the release when
          checking their compatibility. Members running MySQL 8.0.16 or
          lower, or MySQL 5.7, only take into account the major version.
        </p><p>
          In a group running in multi-primary mode with members that use
          different MySQL Server versions, Group Replication
          automatically manages the read-write and read-only status of
          members running MySQL 8.0.17 or higher. If a member leaves the
          group, the members running the version that is now the lowest
          are automatically set to read-write mode. When you change a
          group that was running in single-primary mode to run in
          multi-primary mode, using the
          <a class="link" href="sql-statements.html#udf_group-replication-switch-to-multi-primary-mode"><code class="literal">group_replication_switch_to_multi_primary_mode()</code></a>
          UDF, Group Replication automatically sets members to the
          correct mode. Members are automatically placed in read-only
          mode if they are running a higher MySQL server version than
          the lowest version present in the group, and members running
          the lowest version are placed in read-write mode.
        </p><p>
          For full information on version compatibility in a group and
          how this influences the behavior of a group during an upgrade
          process, see
          <a class="xref" href="group-replication.html#group-replication-online-upgrade-combining-versions" title="18.7.1 Combining Different Member Versions in a Group">Section 18.7.1, “Combining Different Member Versions in a Group”</a>
          .
</p>
</div>

</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="group-replication-details"></a>18.1.4 Group Replication Services</h3>

</div>

</div>

</div>
<div class="toc">
<dl class="toc"><dt><span class="section"><a href="group-replication.html#group-replication-group-membership">18.1.4.1 Group Membership</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-failure-detection">18.1.4.2 Failure Detection</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-fault-tolerance">18.1.4.3 Fault-tolerance</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-observability">18.1.4.4 Observability</a></span></dt></dl>
</div>
<a class="indexterm" name="idm46444260277856"></a><p>
      This section introduces some of the services that Group
      Replication builds on.
</p>
<div class="section">

<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="group-replication-group-membership"></a>18.1.4.1 Group Membership</h4>
</div>
</div>
</div>
<a class="indexterm" name="idm46444260274752"></a><a class="indexterm" name="idm46444260273264"></a><a class="indexterm" name="idm46444260271776"></a><p>
        In MySQL Group Replication, a set of servers forms a replication
        group. A group has a name, which takes the form of a UUID. The
        group is dynamic and servers can leave (either voluntarily or
        involuntarily) and join it at any time. The group adjusts itself
        whenever servers join or leave.
      </p><p>
        If a server joins the group, it automatically brings itself up
        to date by fetching the missing state from an existing server.
        If a server leaves the group, for instance it was taken down for
        maintenance, the remaining servers notice that it has left and
        reconfigure the group automatically.
      </p><p>
        Group Replication has a group membership service that defines
        which servers are online and participating in the group. The
        list of online servers is referred to as a
        <span class="emphasis"><em>view</em></span>. Every server in the group has a
        consistent view of which servers are the members participating
        actively in the group at a given moment in time.
      </p><p>
        Group members must agree not only on transaction commits, but
        also on which is the current view. If existing members agree
        that a new server should become part of the group, the group is
        reconfigured to integrate that server in it, which triggers a
        view change. If a server leaves the group, either voluntarily or
        not, the group dynamically rearranges its configuration and a
        view change is triggered.
      </p><p>
        In the case where a member leaves the group voluntarily, it
        first initiates a dynamic group reconfiguration, during which
        all members have to agree on a new view without the leaving
        server. However, if a member leaves the group involuntarily, for
        example because it has stopped unexpectedly or the network
        connection is down, it cannot initiate the reconfiguration. In
        this situation, Group Replication's failure detection mechanism
        recognizes after a short period of time that the member has
        left, and a reconfiguration of the group without the failed
        member is proposed. As with a member that leaves voluntarily,
        the reconfiguration requires agreement from the majority of
        servers in the group. However, if the group is not able to reach
        agreement, for example because it partitioned in such a way that
        there is no majority of servers online, the system is not able
        to dynamically change the configuration, and blocks to prevent a
        split-brain situation. This situation requires intervention from
        an administrator.
      </p><p>
        It is possible for a member to go offline for a short time, then
        attempt to rejoin the group again before the failure detection
        mechanism has detected its failure, and before the group has
        been reconfigured to remove the member. In this situation, the
        rejoining member forgets its previous state, but if other
        members send it messages that are intended for its pre-crash
        state, this can cause issues including possible data
        inconsistency. If a member in this situation participates in
        XCom's consensus protocol, it could potentially cause XCom to
        deliver different values for the same consensus round, by making
        a different decision before and after failure.
      </p><p>
        To counter this possibility, from MySQL 5.7.22 and in MySQL 8.0,
        servers are given a unique identifier when they join a group.
        This enables Group Replication to be aware of the situation
        where a new incarnation of the same server (with the same
        address but a new identifier) is trying to join the group while
        its old incarnation is still listed as a member. The new
        incarnation is blocked from joining the group until the old
        incarnation can be removed by a reconfiguration. If the
        <a class="link" href="group-replication.html#sysvar_group_replication_member_expel_timeout"><code class="literal">group_replication_member_expel_timeout</code></a>
        system variable has been set to allow additional time for
        members to return to the group before they are expelled, a
        member under suspicion can rejoin as long as it has not actually
        failed. If Group Replication is stopped and restarted on the
        server, the member becomes a new incarnation and cannot rejoin
        until the suspicion times out.
</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="group-replication-failure-detection"></a>18.1.4.2 Failure Detection</h4>

</div>

</div>

</div>
<a class="indexterm" name="idm46444260258912"></a><a class="indexterm" name="idm46444260257424"></a><p>
        Group Replication includes a failure detection mechanism that is
        able to find and report which servers are silent and as such
        assumed to be dead. At a high level, the failure detector is a
        distributed service that provides information about which
        servers may be dead (suspicions). Suspicions are triggered when
        servers go mute. When server A does not receive messages from
        server B during a given period, a timeout occurs and a suspicion
        is raised. Later if the group agrees that the suspicions are
        probably true, then the group decides that a given server has
        indeed failed. This means that the remaining members in the
        group take a coordinated decision to expel a given member.
      </p><p>
        If a server gets isolated from the rest of the group, then it
        suspects that all others have failed. Being unable to secure
        agreement with the group (as it cannot secure a quorum), its
        suspicion does not have consequences. When a server is isolated
        from the group in this way, it is unable to execute any local
        transactions.
      </p><p>
        Where the network is unstable and members frequently lose and
        regain connection to each other in different combinations, it is
        theoretically possible for a group to end up marking all its
        members for expulsion, after which the group would cease to
        exist and have to be set up again. To counter this possibility,
        from MySQL 8.0.20, Group Replication's Group Communication
        System (GCS) tracks the group members that have been marked for
        expulsion, and treats them as if they were in the group of
        suspected members when deciding if there is a majority. This
        ensures at least one member remains in the group and the group
        can continue to exist. When an expelled member has actually been
        removed from the group, GCS removes its record of having marked
        the member for expulsion, so that the member can rejoin the
        group if it is able to.
      </p><p>
        For information on the Group Replication system variables that
        you can configure to specify the responses of working group
        members to failure situations, and the actions taken by group
        members that are suspected of having failed, see
        <a class="xref" href="group-replication.html#group-replication-responses-failure" title="18.6.6 Responses to Failure Detection and Network Partitioning">Section 18.6.6, “Responses to Failure Detection and Network Partitioning”</a>.
</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="group-replication-fault-tolerance"></a>18.1.4.3 Fault-tolerance</h4>

</div>

</div>

</div>
<p>
        MySQL Group Replication builds on an implementation of the Paxos
        distributed algorithm to provide distributed coordination
        between servers. As such, it requires a majority of servers to
        be active to reach quorum and thus make a decision. This has
        direct impact on the number of failures the system can tolerate
        without compromising itself and its overall functionality. The
        number of servers (n) needed to tolerate <code class="literal">f</code>
        failures is then <code class="literal">n = 2 x f + 1</code>.
      </p><p>
        In practice this means that to tolerate one failure the group
        must have three servers in it. As such if one server fails,
        there are still two servers to form a majority (two out of
        three) and allow the system to continue to make decisions
        automatically and progress. However, if a second server fails
        <span class="emphasis"><em>involuntarily</em></span>, then the group (with one
        server left) blocks, because there is no majority to reach a
        decision.
      </p><p>
        The following is a small table illustrating the formula above.
</p>
<div class="informaltable">
<table summary="Relationship between replication group size, the number of servers that constitute a majority, and the number of instant failures that can be tolerated."><col width="0.23%"><col width="0.18%"><col width="0.59%"><thead><tr>
            <th scope="col"><p>
                Group Size
              </p></th>
            <th scope="col"><p>
                Majority
              </p></th>
            <th scope="col"><p>
                Instant Failures Tolerated
              </p></th>
          </tr></thead><tbody><tr>
            <td scope="row"><p>
                1
              </p></td>
            <td><p>
                1
              </p></td>
            <td><p>
                0
              </p></td>
          </tr><tr>
            <td scope="row"><p>
                2
              </p></td>
            <td><p>
                2
              </p></td>
            <td><p>
                0
              </p></td>
          </tr><tr>
            <td scope="row"><p>
                3
              </p></td>
            <td><p>
                2
              </p></td>
            <td><p>
                1
              </p></td>
          </tr><tr>
            <td scope="row"><p>
                4
              </p></td>
            <td><p>
                3
              </p></td>
            <td><p>
                1
              </p></td>
          </tr><tr>
            <td scope="row"><p>
                5
              </p></td>
            <td><p>
                3
              </p></td>
            <td><p>
                2
              </p></td>
          </tr><tr>
            <td scope="row"><p>
                6
              </p></td>
            <td><p>
                4
              </p></td>
            <td><p>
                2
              </p></td>
          </tr><tr>
            <td scope="row"><p>
                7
              </p></td>
            <td><p>
                4
              </p></td>
            <td><p>
                3
              </p></td>
</tr></tbody></table>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="group-replication-observability"></a>18.1.4.4 Observability</h4>

</div>

</div>

</div>
<a class="indexterm" name="idm46444260209184"></a><p>
        There is a lot of automation built into the Group Replication
        plugin. Nonetheless, you might sometimes need to understand what
        is happening behind the scenes. This is where the
        instrumentation of Group Replication and Performance Schema
        becomes important. The entire state of the system (including the
        view, conflict statistics and service states) can be queried
        through Performance Schema tables. The distributed nature of the
        replication protocol and the fact that server instances agree
        and thus synchronize on transactions and metadata makes it
        simpler to inspect the state of the group. For example, you can
        connect to a single server in the group and obtain both local
        and global information by issuing select statements on the Group
        Replication related Performance Schema tables. For more
        information, see <a class="xref" href="group-replication.html#group-replication-monitoring" title="18.3 Monitoring Group Replication">Section 18.3, “Monitoring Group Replication”</a>.
</p>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="group-replication-plugin-architecture"></a>18.1.5 Group Replication Plugin Architecture</h3>

</div>

</div>

</div>
<a class="indexterm" name="idm46444260205264"></a><a class="indexterm" name="idm46444260203776"></a><a class="indexterm" name="idm46444260202272"></a><p>
      MySQL Group Replication is a MySQL plugin and it builds on the
      existing MySQL replication infrastructure, taking advantage of
      features such as the binary log, row-based logging, and global
      transaction identifiers. It integrates with current MySQL
      frameworks, such as the performance schema or plugin and service
      infrastructures. The following figure presents a block diagram
      depicting the overall architecture of MySQL Group Replication.
</p>
<div class="figure">
<a name="idm46444260199904"></a><p class="title"><b>Figure 18.6 Group Replication Plugin Block Diagram</b></p>
<div class="figure-contents">

<div class="mediaobject">
<img src="images/gr-plugin-blocks.png" width="455" height="393" alt="The text following the figure describes the content of the diagram.">
</div>

</div>

</div>
<br class="figure-break"><p>
      The MySQL Group Replication plugin includes a set of APIs for
      capture, apply, and lifecycle, which control how the plugin
      interacts with MySQL Server. There are interfaces to make
      information flow from the server to the plugin and vice versa.
      These interfaces isolate the MySQL Server core from the Group
      Replication plugin, and are mostly hooks placed in the transaction
      execution pipeline. In one direction, from server to the plugin,
      there are notifications for events such as the server starting,
      the server recovering, the server being ready to accept
      connections, and the server being about to commit a transaction.
      In the other direction, the plugin instructs the server to perform
      actions such as committing or aborting ongoing transactions, or
      queuing transactions in the relay log.
    </p><p>
      The next layer of the Group Replication plugin architecture is a
      set of components that react when a notification is routed to
      them. The capture component is responsible for keeping track of
      context related to transactions that are executing. The applier
      component is responsible for executing remote transactions on the
      database. The recovery component manages distributed recovery, and
      is responsible for getting a server that is joining the group up
      to date by selecting the donor, managing the catch up procedure
      and reacting to donor failures.
    </p><p>
      Continuing down the stack, the replication protocol module
      contains the specific logic of the replication protocol. It
      handles conflict detection, and receives and propagates
      transactions to the group.
    </p><p>
      The final two layers of the Group Replication plugin architecture
      are the Group Communication System (GCS) API, and an
      implementation of a Paxos-based group communication engine (XCom).
      The GCS API is a high level API that abstracts the properties
      required to build a replicated state machine (see
      <a class="xref" href="group-replication.html#group-replication-background" title="18.1 Group Replication Background">Section 18.1, “Group Replication Background”</a>). It therefore
      decouples the implementation of the messaging layer from the
      remaining upper layers of the plugin. The group communication
      engine handles communications with the members of the replication
      group.
</p>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a name="group-replication-getting-started"></a>18.2 Getting Started</h2>

</div>

</div>

</div>
<div class="toc">
<dl class="toc"><dt><span class="section"><a href="group-replication.html#group-replication-deploying-in-single-primary-mode">18.2.1 Deploying Group Replication in Single-Primary Mode</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-deploying-locally">18.2.2 Deploying Group Replication Locally</a></span></dt></dl>
</div>
<a class="indexterm" name="idm46444260187264"></a><p>
    MySQL Group Replication is provided as a plugin to MySQL server, and
    each server in a group requires configuration and installation of
    the plugin. This section provides a detailed tutorial with the steps
    required to create a replication group with at least three members.
</p>
<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Tip
</div>
<p>
      An alternative way to deploy multiple instances of MySQL is by
      using InnoDB cluster, which uses Group Replication and wraps it
      in a programmatic environment that enables you to easily work with
      groups of MySQL server instances in the
      <a class="ulink" href="https://dev.mysql.com/doc/mysql-shell/8.0/en/" target="_top">MySQL Shell 8.0 (part of MySQL 8.0)</a>. In addition, InnoDB cluster
      interfaces seamlessly with MySQL Router and simplifies deploying MySQL
      with high availability. See
      <a class="xref" href="mysql-innodb-cluster-userguide.html" title="Chapter 21 InnoDB Cluster">Chapter 21, <i>InnoDB Cluster</i></a>.
</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="group-replication-deploying-in-single-primary-mode"></a>18.2.1 Deploying Group Replication in Single-Primary Mode</h3>

</div>

</div>

</div>
<div class="toc">
<dl class="toc"><dt><span class="section"><a href="group-replication.html#group-replication-getting-started-deploying-instances">18.2.1.1 Deploying Instances for Group Replication</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-configuring-instances">18.2.1.2 Configuring an Instance for Group Replication</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-user-credentials">18.2.1.3 User Credentials</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-launching">18.2.1.4 Launching Group Replication</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-bootstrap">18.2.1.5 Bootstrapping the Group</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-adding-instances">18.2.1.6 Adding Instances to the Group</a></span></dt></dl>
</div>
<a class="indexterm" name="idm46444260181232"></a><p>
      Each of the MySQL server instances in a group can run on an
      independent physical host machine, which is the recommended way to
      deploy Group Replication. This section explains how to create a
      replication group with three MySQL Server instances, each running
      on a different host machine. See
      <a class="xref" href="group-replication.html#group-replication-deploying-locally" title="18.2.2 Deploying Group Replication Locally">Section 18.2.2, “Deploying Group Replication Locally”</a> for
      information about deploying multiple MySQL server instances
      running Group Replication on the same host machine, for example
      for testing purposes.
</p>
<div class="figure">
<a name="idm46444260177920"></a><p class="title"><b>Figure 18.7 Group Architecture</b></p>
<div class="figure-contents">

<div class="mediaobject">
<img src="images/gr-3-server-group.png" width="312" height="332" alt="Three server instances, S1, S2, and S3, are deployed as an interconnected group, and clients communicate with each of the server instances.">
</div>

</div>

</div>
<br class="figure-break"><p>
      This tutorial explains how to get and deploy MySQL Server with the
      Group Replication plugin, how to configure each server instance
      before creating a group, and how to use Performance Schema
      monitoring to verify that everything is working correctly.
</p>
<div class="section">

<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="group-replication-getting-started-deploying-instances"></a>18.2.1.1 Deploying Instances for Group Replication</h4>
</div>
</div>
</div>
<a class="indexterm" name="idm46444260169360"></a><p>
        The first step is to deploy at least three instances of MySQL
        Server, this procedure demonstrates using multiple hosts for the
        instances, named s1, s2 and s3. It is assumed that MySQL Server
        was installed on each of the hosts, see
        <a class="xref" href="installing.html" title="Chapter 2 Installing and Upgrading MySQL">Chapter 2, <i>Installing and Upgrading MySQL</i></a>. Group Replication is a built-in
        MySQL plugin provided with MySQL Server 8.0, therefore no
        additional installation is required. For more background
        information on MySQL plugins, see
        <a class="xref" href="server-administration.html#server-plugins" title="5.6 MySQL Server Plugins">Section 5.6, “MySQL Server Plugins”</a>.
      </p><p>
        In this example, three instances are used for the group, which
        is the minimum number of instances to create a group. Adding
        more instances increases the fault tolerance of the group. For
        example if the group consists of three members, in event of
        failure of one instance the group can continue. But in the event
        of another failure the group can no longer continue processing
        write transactions. By adding more instances, the number of
        servers which can fail while the group continues to process
        transactions also increases. The maximum number of instances
        which can be used in a group is nine. For more information see
        <a class="xref" href="group-replication.html#group-replication-failure-detection" title="18.1.4.2 Failure Detection">Section 18.1.4.2, “Failure Detection”</a>.
</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="group-replication-configuring-instances"></a>18.2.1.2 Configuring an Instance for Group Replication</h4>

</div>

</div>

</div>
<a class="indexterm" name="idm46444260162272"></a><p>
        This section explains the configuration settings required for
        MySQL Server instances that you want to use for Group
        Replication. For background information, see
        <a class="xref" href="group-replication.html#group-replication-requirements-and-limitations" title="18.9 Requirements and Limitations">Section 18.9, “Requirements and Limitations”</a>.
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p><a class="xref" href="group-replication.html#group-replication-storage-engines" title="Storage Engines">Storage Engines</a></p></li><li class="listitem"><p><a class="xref" href="group-replication.html#group-replication-configure-replication-framework" title="Replication Framework">Replication Framework</a></p></li><li class="listitem"><p><a class="xref" href="group-replication.html#group-replication-configure-plugin" title="Group Replication Settings">Group Replication Settings</a></p></li></ul>
</div>

<div class="simplesect">

<div class="titlepage">
<div>

<div class="simple">
<h5 class="title"><a name="group-replication-storage-engines"></a>Storage Engines</h5>

</div>

</div>

</div>
<p>
          For Group Replication, data must be stored in the InnoDB
          transactional storage engine (for details of why, see
          <a class="xref" href="group-replication.html#group-replication-requirements" title="18.9.1 Group Replication Requirements">Section 18.9.1, “Group Replication Requirements”</a>). The use of
          other storage engines, including the temporary
          <a class="link" href="storage-engines.html#memory-storage-engine" title="16.3 The MEMORY Storage Engine"><code class="literal">MEMORY</code></a> storage engine, might
          cause errors in Group Replication. Set the
          <a class="link" href="server-administration.html#sysvar_disabled_storage_engines"><code class="literal">disabled_storage_engines</code></a>
          system variable as follows to prevent their use:
        </p><pre data-lang="ini" class="programlisting">disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"</pre><p>
          Note that with the <a class="link" href="storage-engines.html#myisam-storage-engine" title="16.2 The MyISAM Storage Engine"><code class="literal">MyISAM</code></a> storage
          engine disabled, when you are upgrading a MySQL instance to a
          release where <a class="link" href="programs.html#mysql-upgrade" title="4.4.5 mysql_upgrade — Check and Upgrade MySQL Tables"><span class="command"><strong>mysql_upgrade</strong></span></a> is still used
          (before MySQL 8.0.16), <a class="link" href="programs.html#mysql-upgrade" title="4.4.5 mysql_upgrade — Check and Upgrade MySQL Tables"><span class="command"><strong>mysql_upgrade</strong></span></a> might
          fail with an error. To handle this, you can re-enable that
          storage engine while you run <a class="link" href="programs.html#mysql-upgrade" title="4.4.5 mysql_upgrade — Check and Upgrade MySQL Tables"><span class="command"><strong>mysql_upgrade</strong></span></a>,
          then disable it again when you restart the server. For more
          information, see <a class="xref" href="programs.html#mysql-upgrade" title="4.4.5 mysql_upgrade — Check and Upgrade MySQL Tables">Section 4.4.5, “<span class="command"><strong>mysql_upgrade</strong></span> — Check and Upgrade MySQL Tables”</a>.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h5 class="title"><a name="group-replication-configure-replication-framework"></a>Replication Framework</h5>

</div>

</div>

</div>
<p>
          The following settings configure replication according to the
          MySQL Group Replication requirements.
        </p><pre data-lang="ini" class="programlisting">server_id=1
gtid_mode=ON
enforce_gtid_consistency=ON
binlog_checksum=NONE</pre><p>
          These settings configure the server to use the unique
          identifier number 1, to enable
          <a class="xref" href="replication.html#replication-gtids" title="17.1.3 Replication with Global Transaction Identifiers">Section 17.1.3, “Replication with Global Transaction Identifiers”</a>, to allow execution of
          only statements that can be safely logged using a GTID, and to
          disable writing checksums for events written to the binary
          log.
        </p><p>
          If you are using a version of MySQL earlier than 8.0.3, where
          the defaults were improved for replication, you need to add
          these lines to the member's option file.
        </p><pre data-lang="ini" class="programlisting">log_bin=binlog
log_slave_updates=ON
binlog_format=ROW
master_info_repository=TABLE
relay_log_info_repository=TABLE</pre><p>
          These settings instruct the server to turn on binary logging,
          use row-based format, to store replication metadata in system
          tables instead of files, and disable binary log event
          checksums. For more details see
          <a class="xref" href="group-replication.html#group-replication-requirements" title="18.9.1 Group Replication Requirements">Section 18.9.1, “Group Replication Requirements”</a>.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h5 class="title"><a name="group-replication-configure-plugin"></a>Group Replication Settings</h5>

</div>

</div>

</div>
<p>
          At this point the option file ensures that the server is
          configured and is instructed to instantiate the replication
          infrastructure under a given configuration. The following
          section configures the Group Replication settings for the
          server.
        </p><pre data-lang="ini" class="programlisting">plugin_load_add='group_replication.so'
group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
group_replication_start_on_boot=off
group_replication_local_address= "s1:33061"
group_replication_group_seeds= "s1:33061,s2:33061,s3:33061"
group_replication_bootstrap_group=off</pre>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              <code class="option">plugin-load-add</code> adds the Group
              Replication plugin to the list of plugins which the server
              loads at startup. This is preferable in a production
              deployment to installing the plugin manually.
            </p></li><li class="listitem"><p>
              Configuring
              <a class="link" href="group-replication.html#sysvar_group_replication_group_name"><code class="literal">group_replication_group_name</code></a>
              tells the plugin that the group that it is joining, or
              creating, is named
              "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa".
            </p><p>
              The value of
              <a class="link" href="group-replication.html#sysvar_group_replication_group_name"><code class="literal">group_replication_group_name</code></a>
              must be a valid UUID. This UUID is used internally when
              setting GTIDs for Group Replication events in the binary
              log. You can use <code class="literal">SELECT UUID()</code> to
              generate a UUID.
            </p></li><li class="listitem"><p>
              Configuring the
              <a class="link" href="group-replication.html#sysvar_group_replication_start_on_boot"><code class="literal">group_replication_start_on_boot</code></a>
              variable to <code class="literal">off</code> instructs the plugin to
              not start operations automatically when the server starts.
              This is important when setting up Group Replication as it
              ensures you can configure the server before manually
              starting the plugin. Once the member is configured you can
              set
              <a class="link" href="group-replication.html#sysvar_group_replication_start_on_boot"><code class="literal">group_replication_start_on_boot</code></a>
              to <code class="literal">on</code> so that Group Replication starts
              automatically upon server boot.
            </p></li><li class="listitem"><p>
              Configuring
              <a class="link" href="group-replication.html#sysvar_group_replication_local_address"><code class="literal">group_replication_local_address</code></a>
              sets the network address and port which the member uses
              for internal communication with other members in the
              group. Group Replication uses this address for internal
              member-to-member connections involving remote instances of
              the group communication engine (XCom, a Paxos variant).
</p>
<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Important
</div>
<p>
                The group replication local address must be different to
                the <a class="link" href="server-administration.html#sysvar_hostname"><code class="literal">hostname</code></a> and
                <a class="link" href="server-administration.html#sysvar_port"><code class="literal">port</code></a> used for SQL and
                it must not be used for client applications. It must be
                only be used for internal communication between the
                members of the group while running Group Replication.
</p>
</div>
<p>
              The network address configured by
              <a class="link" href="group-replication.html#sysvar_group_replication_local_address"><code class="literal">group_replication_local_address</code></a>
              must be resolvable by all group members. For example, if
              each server instance is on a different machine with a
              fixed network address, you could use the IP address of the
              machine, such as 10.0.0.1. If you use a host name, you
              must use a fully qualified name, and ensure it is
              resolvable through DNS, correctly configured
              <code class="literal">/etc/hosts</code> files, or other name
              resolution processes. From MySQL 8.0.14, IPv6 addresses
              (or host names that resolve to them) can be used as well
              as IPv4 addresses. A group can contain a mix of members
              using IPv6 and members using IPv4. For more information on
              Group Replication support for IPv6 networks and on mixed
              IPv4 and IPv6 groups, see
              <a class="xref" href="group-replication.html#group-replication-ipv6" title="18.4.5 Support For IPv6 And For Mixed IPv6 And IPv4 Groups">Section 18.4.5, “Support For IPv6 And For Mixed IPv6 And IPv4 Groups”</a>.
            </p><p>
              The recommended port for
              <a class="link" href="group-replication.html#sysvar_group_replication_local_address"><code class="literal">group_replication_local_address</code></a>
              is 33061.
              <a class="link" href="group-replication.html#sysvar_group_replication_local_address"><code class="literal">group_replication_local_address</code></a>
              is used by Group Replication as the unique identifier for
              a group member within the replication group. You can use
              the same port for all members of a replication group as
              long as the host names or IP addresses are all different,
              as demonstrated in this tutorial. Alternatively you can
              use the same host name or IP address for all members as
              long as the ports are all different, for example as shown
              in <a class="xref" href="group-replication.html#group-replication-deploying-locally" title="18.2.2 Deploying Group Replication Locally">Section 18.2.2, “Deploying Group Replication Locally”</a>.
</p>
<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Important
</div>
<p>
                Although the group replication local address is
                different to the
                <a class="link" href="server-administration.html#sysvar_hostname"><code class="literal">hostname</code></a> and
                <a class="link" href="server-administration.html#sysvar_port"><code class="literal">port</code></a> used for SQL,
                Group Replication's distributed recovery process for
                joining members can fail if the server cannot correctly
                identify the other members using the server's SQL
                <a class="link" href="server-administration.html#sysvar_hostname"><code class="literal">hostname</code></a>. It is
                recommended that operating systems running MySQL have a
                properly configured unique
                <a class="link" href="server-administration.html#sysvar_hostname"><code class="literal">hostname</code></a>, either using
                DNS or local settings. The
                <a class="link" href="server-administration.html#sysvar_hostname"><code class="literal">hostname</code></a> can be
                verified in the <code class="literal">Member_host</code> column of
                the
                <a class="link" href="performance-schema.html#replication-group-members-table" title="26.12.11.9 The replication_group_members Table"><code class="literal">performance_schema.replication_group_members</code></a>
                table. If multiple group members externalize a default
                <a class="link" href="server-administration.html#sysvar_hostname"><code class="literal">hostname</code></a> set by the
                operating system, there is a chance of the member not
                resolving to the correct member address and not being
                able to join the group. In such a situation use
                <a class="link" href="replication.html#sysvar_report_host"><code class="literal">report_host</code></a> to
                configure a unique
                <a class="link" href="server-administration.html#sysvar_hostname"><code class="literal">hostname</code></a> to be
                externalized by each of the servers.
</p>
</div>
</li><li class="listitem"><p>
              Configuring
              <a class="link" href="group-replication.html#sysvar_group_replication_group_seeds"><code class="literal">group_replication_group_seeds</code></a>
              sets the hostname and port of the group members which are
              used by the new member to establish its connection to the
              group. These members are called the seed members. Once the
              connection is established, the group membership
              information is listed at
              <a class="link" href="performance-schema.html#replication-group-members-table" title="26.12.11.9 The replication_group_members Table"><code class="literal">performance_schema.replication_group_members</code></a>.
              Usually the
              <a class="link" href="group-replication.html#sysvar_group_replication_group_seeds"><code class="literal">group_replication_group_seeds</code></a>
              list contains the <code class="literal">hostname:port</code> of each
              of the group member's
              <a class="link" href="group-replication.html#sysvar_group_replication_local_address"><code class="literal">group_replication_local_address</code></a>,
              but this is not obligatory and a subset of the group
              members can be chosen as seeds.
</p>
<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Important
</div>
<p>
                The <code class="literal">hostname:port</code> listed in
                <a class="link" href="group-replication.html#sysvar_group_replication_group_seeds"><code class="literal">group_replication_group_seeds</code></a>
                is the seed member's internal network address,
                configured by
                <a class="link" href="group-replication.html#sysvar_group_replication_local_address"><code class="literal">group_replication_local_address</code></a>
                and not the SQL <code class="literal">hostname:port</code> used
                for client connections, and shown for example in
                <a class="link" href="performance-schema.html#replication-group-members-table" title="26.12.11.9 The replication_group_members Table"><code class="literal">performance_schema.replication_group_members</code></a>
                table.
</p>
</div>
<p>
              The server that starts the group does not make use of this
              option, since it is the initial server and as such, it is
              in charge of bootstrapping the group. In other words, any
              existing data which is on the server bootstrapping the
              group is what is used as the data for the next joining
              member. The second server joining asks the one and only
              member in the group to join, any missing data on the
              second server is replicated from the donor data on the
              bootstrapping member, and then the group expands. The
              third server joining can ask any of these two to join,
              data is synchronized to the new member, and then the group
              expands again. Subsequent servers repeat this procedure
              when joining.
</p>
<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Warning
</div>
<p>
                When joining multiple servers at the same time, make
                sure that they point to seed members that are already in
                the group. Do not use members that are also joining the
                group as seeds, because they might not yet be in the
                group when contacted.
              </p><p>
                It is good practice to start the bootstrap member first,
                and let it create the group. Then make it the seed
                member for the rest of the members that are joining.
                This ensures that there is a group formed when joining
                the rest of the members.
              </p><p>
                Creating a group and joining multiple members at the
                same time is not supported. It might work, but chances
                are that the operations race and then the act of joining
                the group ends up in an error or a time out.
</p>
</div>
<p>
              A joining member must communicate with a seed member using
              the same protocol (IPv4 or IPv6) that the seed member
              advertises in the
              <a class="link" href="group-replication.html#sysvar_group_replication_group_seeds"><code class="literal">group_replication_group_seeds</code></a>
              option. For the purpose of IP address whitelisting for
              Group Replication, the whitelist on the seed member must
              include an IP address for the joining member for the
              protocol offered by the seed member, or a host name that
              resolves to an address for that protocol. This address or
              host name must be set up and whitelisted in addition to
              the joining member's
              <a class="link" href="group-replication.html#sysvar_group_replication_local_address"><code class="literal">group_replication_local_address</code></a>
              if the protocol for that address does not match the seed
              member's advertised protocol. If a joining member does not
              have a whitelisted address for the appropriate protocol,
              its connection attempt is refused. For more information,
              see
              <a class="xref" href="group-replication.html#group-replication-ip-address-whitelisting" title="18.5.1 Group Replication IP Address Whitelisting">Section 18.5.1, “Group Replication IP Address Whitelisting”</a>.
            </p></li><li class="listitem"><p>
              Configuring
              <a class="link" href="group-replication.html#sysvar_group_replication_bootstrap_group"><code class="literal">group_replication_bootstrap_group</code></a>
              instructs the plugin whether to bootstrap the group or
              not. In this case, even though s1 is the first member of
              the group we set this variable to off in the option file.
              Instead we configure
              <a class="link" href="group-replication.html#sysvar_group_replication_bootstrap_group"><code class="literal">group_replication_bootstrap_group</code></a>
              when the instance is running, to ensure that only one
              member actually bootstraps the group.
</p>
<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Important
</div>
<p>
                The
                <a class="link" href="group-replication.html#sysvar_group_replication_bootstrap_group"><code class="literal">group_replication_bootstrap_group</code></a>
                variable must only be enabled on one server instance
                belonging to a group at any time, usually the first time
                you bootstrap the group (or in case the entire group is
                brought down and back up again). If you bootstrap the
                group multiple times, for example when multiple server
                instances have this option set, then they could create
                an artificial split brain scenario, in which two
                distinct groups with the same name exist. Always set
                <a class="link" href="group-replication.html#sysvar_group_replication_bootstrap_group"><code class="literal">group_replication_bootstrap_group=off</code></a>
                after the first server instance comes online.
</p>
</div>
</li></ul>
</div>
<p>
          If you are using an instance running a version of MySQL
          earlier than 8.0.2, you need to also configure the
          <a class="link" href="replication.html#sysvar_transaction_write_set_extraction"><code class="literal">transaction_write_set_extraction</code></a>
          variable to XXHASH64. This variable instructs the server that
          for each transaction it has to collect the write set and
          encode it as a hash using the XXHASH64 hashing algorithm. From
          MySQL 8.0.2, this setting is the default, otherwise add the
          following to the option file:
        </p><pre data-lang="ini" class="programlisting">transaction_write_set_extraction=XXHASH64</pre><p>
          Configuration for all servers in the group is quite similar.
          You need to change the specifics about each server (for
          example <a class="link" href="replication.html#sysvar_server_id"><code class="literal">server_id</code></a>,
          <a class="link" href="server-administration.html#sysvar_datadir"><code class="literal">datadir</code></a>,
          <a class="link" href="group-replication.html#sysvar_group_replication_local_address"><code class="literal">group_replication_local_address</code></a>).
          This is illustrated later in this tutorial.
</p>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="group-replication-user-credentials"></a>18.2.1.3 User Credentials</h4>

</div>

</div>

</div>
<a class="indexterm" name="idm46444260053904"></a><p>
        Group Replication uses a distributed recovery process to
        synchronize group members when joining them to the group.
        Distributed recovery involves transferring transactions from a
        donor's binary log to a joining member using a replication
        channel named <code class="literal">group_replication_recovery</code>. You
        must therefore set up a replication user with the correct
        permissions so that Group Replication can establish direct
        member-to-member replication channels. If group members have
        been set up to support the use of a remote cloning operation as
        part of distributed recovery, which is available from MySQL
        8.0.17, this replication user is also used as the clone user on
        the donor , and requires the correct permissions for this role
        too. For a complete description of distributed recovery, see
        <a class="xref" href="group-replication.html#group-replication-distributed-recovery" title="18.4.3 Distributed Recovery">Section 18.4.3, “Distributed Recovery”</a>.
      </p><p>
        The process of setting up the replication user for distributed
        recovery can be captured in the binary log, and then you can
        rely on distributed recovery to replicate the statements used to
        create the user. Alternatively, you can disable binary logging
        before creating the replication user, and then create the user
        manually on each member, for example if you want to avoid the
        changes being propagated to other server instances. If you do
        this, ensure you re-enable binary logging once you have
        configured the user.
      </p><p>
        If you have set up cloning for your replication group, the
        replication user and password used by the donor for the
        <code class="literal">group_replication_recovery</code> replication
        channel are transferred to the joining member after cloning, and
        used by the joining member afterwards, so they must be valid
        there. All group members that received state transfer by a
        remote cloning operation therefore use the same replication user
        and password for distributed recovery.
</p>
<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Important
</div>
<p>
          If distributed recovery connections for your group use SSL,
          the replication user must be created on each server
          <span class="emphasis"><em>before</em></span> the joining member connects to the
          donor. For instructions to set up SSL for distributed recovery
          connections, see
          <a class="xref" href="group-replication.html#group-replication-secure-socket-layer-support-ssl" title="18.5.2 Group Replication Secure Socket Layer (SSL) Support">Section 18.5.2, “Group Replication Secure Socket Layer (SSL) Support”</a>
</p>
</div>
<p>
        To create the replication user for distributed recovery, follow
        these steps:
</p>
<div class="orderedlist">
<ol class="orderedlist" type="1"><li class="listitem"><p>
            Start the MySQL server instance, then connect a client to
            it.
          </p></li><li class="listitem"><p>
            If you want to disable binary logging in order to create the
            replication user separately on each instance, do so by
            issuing the following statement:
          </p><pre data-lang="sql" class="programlisting">mysql&gt; <strong class="userinput"><code>SET SQL_LOG_BIN=0;</code></strong>
</pre></li><li class="listitem"><p>
            Create a MySQL user with the
            <a class="link" href="security.html#priv_replication-slave"><code class="literal">REPLICATION SLAVE</code></a> privilege
            to use for distributed recovery, and if the server is set up
            to support cloning, the
            <a class="link" href="security.html#priv_backup-admin"><code class="literal">BACKUP_ADMIN</code></a> privilege to use
            as the donor in a cloning operation. In this example the
            user <em class="replaceable"><code>rpl_user</code></em> with the password
            <em class="replaceable"><code>password</code></em> is shown. When
            configuring your servers use a suitable user name and
            password:
          </p><pre data-lang="sql" class="programlisting">mysql&gt; <strong class="userinput"><code>CREATE USER <em class="replaceable"><code>rpl_user</code></em>@'%' IDENTIFIED BY '<em class="replaceable"><code>password</code></em>';</code></strong>
mysql&gt; <strong class="userinput"><code>GRANT REPLICATION SLAVE ON *.* TO <em class="replaceable"><code>rpl_user</code></em>@'%';</code></strong>
mysql&gt; <strong class="userinput"><code>GRANT BACKUP_ADMIN ON *.* TO <em class="replaceable"><code>rpl_user</code></em>@'%';</code></strong>
mysql&gt; <strong class="userinput"><code>FLUSH PRIVILEGES;</code></strong>
</pre></li><li class="listitem"><p>
            If you disabled binary logging, enable it again as soon as
            you have created the user, by issuing the following
            statement:
          </p><pre data-lang="sql" class="programlisting">mysql&gt; <strong class="userinput"><code>SET SQL_LOG_BIN=1;</code></strong>
</pre></li><li class="listitem"><p>
            When the user has been configured, use a
            <a class="link" href="sql-statements.html#change-master-to" title="13.4.2.1 CHANGE MASTER TO Statement"><code class="literal">CHANGE MASTER TO</code></a> statement to
            configure the server to use the given credentials for state
            transfer by distributed recovery or a remote cloning
            operation. Issue the following statement, replacing
            <em class="replaceable"><code>rpl_user</code></em> and
            <em class="replaceable"><code>password</code></em> with the values used
            when creating the user:
          </p><pre data-lang="sql" class="programlisting">mysql&gt; <strong class="userinput"><code>CHANGE MASTER TO MASTER_USER='<em class="replaceable"><code>rpl_user</code></em>', MASTER_PASSWORD='<em class="replaceable"><code>password</code></em>' \\
		      FOR CHANNEL 'group_replication_recovery';</code></strong>
      </pre><p>
            If these credentials are not set correctly for the
            <code class="literal">group_replication_recovery</code> replication
            channel and the <code class="literal">rpl_user</code> as shown, the
            server cannot connect to a donor to carry out state transfer
            and therefore cannot join the group.
</p></li></ol>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h5 class="title"><a name="group-replication-caching-sha2-user-credentials"></a>Using Group Replication and the Caching SHA-2 User Credentials Plugin</h5>

</div>

</div>

</div>
<p>
          By default, users created in MySQL 8 use
          <a class="xref" href="security.html#caching-sha2-pluggable-authentication" title="6.4.1.2 Caching SHA-2 Pluggable Authentication">Section 6.4.1.2, “Caching SHA-2 Pluggable Authentication”</a>. If
          the <em class="replaceable"><code>rpl_user</code></em> you configure for
          distributed recovery uses the caching SHA-2 authentication
          plugin and you are not using
          <a class="xref" href="group-replication.html#group-replication-secure-socket-layer-support-ssl" title="18.5.2 Group Replication Secure Socket Layer (SSL) Support">Section 18.5.2, “Group Replication Secure Socket Layer (SSL) Support”</a>
          for the <code class="literal">group_replication_recovery</code>
          replication channel, RSA key-pairs are used for password
          exchange, see <a class="xref" href="security.html#creating-ssl-rsa-files" title="6.3.3 Creating SSL and RSA Certificates and Keys">Section 6.3.3, “Creating SSL and RSA Certificates and Keys”</a>. You
          can either copy the public key of the
          <code class="literal">rpl_user</code> to the joining member, or
          configure the donors to provide the public key when requested.
        </p><p>
          The more secure approach is to copy the public key of the
          <code class="literal">rpl_user</code> to the joining member. Then you
          need to configure the
          <a class="link" href="group-replication.html#sysvar_group_replication_recovery_public_key_path"><code class="literal">group_replication_recovery_public_key_path</code></a>
          system variable on the joining member with the path to the
          public key for the <code class="literal">rpl_user</code>.
        </p><p>
          Optionally, a less secure approach is to set
          <a class="link" href="group-replication.html#sysvar_group_replication_recovery_get_public_key"><code class="literal">group_replication_recovery_get_public_key=ON</code></a>
          on donors so that they provide the public key of the
          <code class="literal">rpl_user</code> to joining members. There is no
          way to verify the identity of a server, therefore only set
          <a class="link" href="group-replication.html#sysvar_group_replication_recovery_get_public_key"><code class="literal">group_replication_recovery_get_public_key=ON</code></a>
          when you are sure there is no risk of server identity being
          compromised, for example by a man-in-the-middle attack.
</p>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="group-replication-launching"></a>18.2.1.4 Launching Group Replication</h4>

</div>

</div>

</div>
<a class="indexterm" name="idm46444260004400"></a><p>
        Once server s1 has been configured and started, install the
        Group Replication plugin. If you used
        <code class="literal">plugin_load_add='group_replication.so'</code> in the
        option file then the Group Replication plugin is installed and
        you can proceed to the next step. In the event that you decide
        to install the plugin manually, connect to the server and issue
        the following:
</p><pre data-lang="sql" class="programlisting"><strong class="userinput"><code>INSTALL PLUGIN group_replication SONAME 'group_replication.so';</code></strong></pre>
<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Important
</div>
<p>
          The <code class="literal">mysql.session</code> user must exist before
          you can load Group Replication.
          <code class="literal">mysql.session</code> was added in MySQL version
          8.0.2. If your data dictionary was initialized using an
          earlier version you must perform the MySQL upgrade procedure
          (see <a class="xref" href="installing.html#upgrading" title="2.11 Upgrading MySQL">Section 2.11, “Upgrading MySQL”</a>). If the upgrade is not run,
          Group Replication fails to start with the error message
          <span class="errortext">There was an error when trying to access the server
          with user: mysql.session@localhost. Make sure the user is
          present in the server and that mysql_upgrade was ran after a
          server update.</span>.
</p>
</div>
<p>
        To check that the plugin was installed successfully, issue
        <code class="literal">SHOW PLUGINS;</code> and check the output. It should
        show something like this:
      </p><pre data-lang="sql" class="programlisting">mysql&gt; <strong class="userinput"><code>SHOW PLUGINS;</code></strong>
+----------------------------+----------+--------------------+----------------------+-------------+
| Name                       | Status   | Type               | Library              | License     |
+----------------------------+----------+--------------------+----------------------+-------------+
| binlog                     | ACTIVE   | STORAGE ENGINE     | NULL                 | PROPRIETARY |

(...)

| group_replication          | ACTIVE   | GROUP REPLICATION  | group_replication.so | PROPRIETARY |
+----------------------------+----------+--------------------+----------------------+-------------+</pre>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="group-replication-bootstrap"></a>18.2.1.5 Bootstrapping the Group</h4>

</div>

</div>

</div>
<p>
        The process of starting a group for the first time is called
        bootstrapping. You use the
        <a class="link" href="group-replication.html#sysvar_group_replication_bootstrap_group"><code class="literal">group_replication_bootstrap_group</code></a>
        system variable to bootstrap a group. The bootstrap should only
        be done by a single server, the one that starts the group and
        only once. This is why the value of the
        <a class="link" href="group-replication.html#sysvar_group_replication_bootstrap_group"><code class="literal">group_replication_bootstrap_group</code></a>
        option was not stored in the instance's option file. If it is
        saved in the option file, upon restart the server automatically
        bootstraps a second group with the same name. This would result
        in two distinct groups with the same name. The same reasoning
        applies to stopping and restarting the plugin with this option
        set to <code class="literal">ON</code>. Therefore to safely bootstrap the
        group, connect to s1 and issue:
      </p><pre data-lang="sql" class="programlisting">mysql&gt; <strong class="userinput"><code>SET GLOBAL group_replication_bootstrap_group=ON;</code></strong>
mysql&gt; <strong class="userinput"><code>START GROUP_REPLICATION;</code></strong>
mysql&gt; <strong class="userinput"><code>SET GLOBAL group_replication_bootstrap_group=OFF;</code></strong>
</pre><p>
        Once the <a class="link" href="sql-statements.html#start-group-replication" title="13.4.3.1 START GROUP_REPLICATION Statement"><code class="literal">START GROUP_REPLICATION</code></a>
        statement returns, the group has been started. You can check
        that the group is now created and that there is one member in
        it:
      </p><pre data-lang="sql" class="programlisting">mysql&gt; <strong class="userinput"><code>SELECT * FROM performance_schema.replication_group_members;</code></strong>
+---------------------------+--------------------------------------+-------------+-------------+---------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE  |
+---------------------------+--------------------------------------+-------------+-------------+---------------+
| group_replication_applier | ce9be252-2b71-11e6-b8f4-00212844f856 |   s1        |       3306  | ONLINE        |
+---------------------------+--------------------------------------+-------------+-------------+---------------+
</pre><p>
        The information in this table confirms that there is a member in
        the group with the unique identifier
        <code class="literal">ce9be252-2b71-11e6-b8f4-00212844f856</code>, that it
        is <code class="literal">ONLINE</code> and is at <code class="literal">s1</code>
        listening for client connections on port
        <code class="literal">3306</code>.
      </p><p>
        For the purpose of demonstrating that the server is indeed in a
        group and that it is able to handle load, create a table and add
        some content to it.
      </p><pre data-lang="sql" class="programlisting">mysql&gt; <strong class="userinput"><code>CREATE DATABASE test;</code></strong>
mysql&gt; <strong class="userinput"><code>USE test;</code></strong>
mysql&gt; <strong class="userinput"><code>CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 TEXT NOT NULL);</code></strong>
mysql&gt; <strong class="userinput"><code>INSERT INTO t1 VALUES (1, 'Luis');</code></strong>
</pre><p>
        Check the content of table <code class="literal">t1</code> and the binary
        log.
      </p><pre data-lang="sql" class="programlisting">mysql&gt; <strong class="userinput"><code>SELECT * FROM t1;</code></strong>
+----+------+
| c1 | c2   |
+----+------+
|  1 | Luis |
+----+------+

mysql&gt; <strong class="userinput"><code>SHOW BINLOG EVENTS;</code></strong>
+---------------+-----+----------------+-----------+-------------+--------------------------------------------------------------------+
| Log_name      | Pos | Event_type     | Server_id | End_log_pos | Info                                                               |
+---------------+-----+----------------+-----------+-------------+--------------------------------------------------------------------+
| binlog.000001 |   4 | Format_desc    |         1 |         123 | Server ver: 8.0.22-log, Binlog ver: 4                              |
| binlog.000001 | 123 | Previous_gtids |         1 |         150 |                                                                    |
| binlog.000001 | 150 | Gtid           |         1 |         211 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:1'  |
| binlog.000001 | 211 | Query          |         1 |         270 | BEGIN                                                              |
| binlog.000001 | 270 | View_change    |         1 |         369 | view_id=14724817264259180:1                                        |
| binlog.000001 | 369 | Query          |         1 |         434 | COMMIT                                                             |
| binlog.000001 | 434 | Gtid           |         1 |         495 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:2'  |
| binlog.000001 | 495 | Query          |         1 |         585 | CREATE DATABASE test                                               |
| binlog.000001 | 585 | Gtid           |         1 |         646 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:3'  |
| binlog.000001 | 646 | Query          |         1 |         770 | use `test`; CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 TEXT NOT NULL) |
| binlog.000001 | 770 | Gtid           |         1 |         831 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:4'  |
| binlog.000001 | 831 | Query          |         1 |         899 | BEGIN                                                              |
| binlog.000001 | 899 | Table_map      |         1 |         942 | table_id: 108 (test.t1)                                            |
| binlog.000001 | 942 | Write_rows     |         1 |         984 | table_id: 108 flags: STMT_END_F                                    |
| binlog.000001 | 984 | Xid            |         1 |        1011 | COMMIT /* xid=38 */                                                |
+---------------+-----+----------------+-----------+-------------+--------------------------------------------------------------------+
</pre><p>
        As seen above, the database and the table objects were created
        and their corresponding DDL statements were written to the
        binary log. Also, the data was inserted into the table and
        written to the binary log, so it can be used for distributed
        recovery by state transfer from a donor's binary log.
</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="group-replication-adding-instances"></a>18.2.1.6 Adding Instances to the Group</h4>

</div>

</div>

</div>
<a class="indexterm" name="idm46444259961280"></a><p>
        At this point, the group has one member in it, server s1, which
        has some data in it. It is now time to expand the group by
        adding the other two servers configured previously.
</p>
<div class="section">

<div class="titlepage">
<div>
<div>
<h5 class="title"><a name="group-replication-adding-a-second-instance"></a>18.2.1.6.1 Adding a Second Instance</h5>
</div>
</div>
</div>
<a class="indexterm" name="idm46444259957952"></a><p>
          In order to add a second instance, server s2, first create the
          configuration file for it. The configuration is similar to the
          one used for server s1, except for things such as the
          <a class="link" href="replication.html#sysvar_server_id"><code class="literal">server_id</code></a>. These different
          lines are highlighted in the listing below.
        </p><pre data-lang="ini" class="programlisting">[mysqld]

#
# Disable other storage engines
#
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"

#
# Replication configuration parameters
#
server_id=2
gtid_mode=ON
enforce_gtid_consistency=ON
binlog_checksum=NONE

#
# Group Replication configuration
#
transaction_write_set_extraction=XXHASH64
group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
group_replication_start_on_boot=off
group_replication_local_address= "s2:33061"
group_replication_group_seeds= "s1:33061,s2:33061,s3:33061"
group_replication_bootstrap_group= off</pre><p>
          Similar to the procedure for server s1, with the option file
          in place you launch the server. Then configure the distributed
          recovery credentials as follows. The commands are the same as
          used when setting up server s1 as the user is shared within
          the group. This member needs to have the same replication user
          configured in
          <a class="xref" href="group-replication.html#group-replication-user-credentials" title="18.2.1.3 User Credentials">Section 18.2.1.3, “User Credentials”</a>. If you
          are relying on distributed recovery to configure the user on
          all members, when s2 connects to the seed s1 the replication
          user is replicated or cloned to s1. If you did not have binary
          logging enabled when you configured the user credentials on
          s1, and a remote cloning operation is not used for state
          transfer, you must create the replication user on s2. In this
          case, connect to s2 and issue:
        </p><pre data-lang="sql" class="programlisting"><strong class="userinput"><code>SET SQL_LOG_BIN=0;</code></strong>
<strong class="userinput"><code>CREATE USER <em class="replaceable"><code>rpl_user</code></em>@'%' IDENTIFIED BY '<em class="replaceable"><code>password</code></em>';</code></strong>
<strong class="userinput"><code>GRANT REPLICATION SLAVE ON *.* TO <em class="replaceable"><code>rpl_user</code></em>@'%';</code></strong>
<strong class="userinput"><code>GRANT BACKUP_ADMIN ON *.* TO <em class="replaceable"><code>rpl_user</code></em>@'%';</code></strong>
<strong class="userinput"><code>SET SQL_LOG_BIN=1;</code></strong>
<strong class="userinput"><code>CHANGE MASTER TO MASTER_USER='<em class="replaceable"><code>rpl_user</code></em>', MASTER_PASSWORD='<em class="replaceable"><code>password</code></em>' \\
	FOR CHANNEL 'group_replication_recovery';
</code></strong></pre>
<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Tip
</div>
<p>
            If you are using the caching SHA-2 authentication plugin,
            the default in MySQL 8, see
            <a class="xref" href="group-replication.html#group-replication-caching-sha2-user-credentials" title="Using Group Replication and the Caching SHA-2 User Credentials Plugin">Using Group Replication and the Caching SHA-2 User Credentials Plugin</a>.
</p>
</div>
<p>
          If necessary, install the Group Replication plugin, see
          <a class="xref" href="group-replication.html#group-replication-launching" title="18.2.1.4 Launching Group Replication">Section 18.2.1.4, “Launching Group Replication”</a>.
        </p><p>
          Start Group Replication and s2 starts the process of joining
          the group.
        </p><pre data-lang="sql" class="programlisting">mysql&gt; START GROUP_REPLICATION;</pre><p>
          Unlike the previous steps that were the same as those executed
          on s1, here there is a difference in that you do
          <span class="emphasis"><em>not</em></span> need to boostrap the group because
          the group already exiists. In other words on s2
          <a class="link" href="group-replication.html#sysvar_group_replication_bootstrap_group"><code class="literal">group_replication_bootstrap_group</code></a>
          is set to off, and you do not issue <code class="literal">SET GLOBAL
          group_replication_bootstrap_group=ON;</code> before
          starting Group Replication, because the group has already been
          created and bootstrapped by server s1. At this point server s2
          only needs to be added to the already existing group.
</p>
<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Tip
</div>
<p>
            When Group Replication starts successfully and the server
            joins the group it checks the
            <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only</code></a> variable.
            By setting <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only</code></a>
            to ON in the member's configuration file, you can
            ensure that servers which fail when starting Group
            Replication for any reason do not accept transactions. If
            the server should join the group as read-write instance, for
            example as the primary in a single-primary group or as a
            member of a multi-primary group, when the
            <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only</code></a> variable is
            set to ON then it is set to OFF upon joining the group.
</p>
</div>
<p>
          Checking the
          <a class="link" href="performance-schema.html#replication-group-members-table" title="26.12.11.9 The replication_group_members Table"><code class="literal">performance_schema.replication_group_members</code></a>
          table again shows that there are now two
          <span class="emphasis"><em>ONLINE</em></span> servers in the group.
        </p><pre data-lang="sql" class="programlisting">mysql&gt; <strong class="userinput"><code>SELECT * FROM performance_schema.replication_group_members;</code></strong>
+---------------------------+--------------------------------------+-------------+-------------+---------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE  |
+---------------------------+--------------------------------------+-------------+-------------+---------------+
| group_replication_applier | 395409e1-6dfa-11e6-970b-00212844f856 |   s1        |        3306 | ONLINE        |
| group_replication_applier | ac39f1e6-6dfa-11e6-a69d-00212844f856 |   s2        |        3306 | ONLINE        |
+---------------------------+--------------------------------------+-------------+-------------+---------------+
</pre><p>
          When s2 attempted to join the group,
          <a class="xref" href="group-replication.html#group-replication-distributed-recovery" title="18.4.3 Distributed Recovery">Section 18.4.3, “Distributed Recovery”</a>
          ensured that s2 applied the same transactions which s1 had
          applied. Once this process completed, s2 could join the group
          as a member, and at this point it is marked as ONLINE. In
          other words it must have already caught up with server s1
          automatically. Once s2 is ONLINE, it then begins to process
          transactions with the group. Verify that s2 has indeed
          synchronized with server s1 as follows.
        </p><pre data-lang="sql" class="programlisting">mysql&gt; <strong class="userinput"><code>SHOW DATABASES LIKE 'test';</code></strong>
+-----------------+
| Database (test) |
+-----------------+
| test            |
+-----------------+

mysql&gt; <strong class="userinput"><code>SELECT * FROM test.t1;</code></strong>
+----+------+
| c1 | c2   |
+----+------+
|  1 | Luis |
+----+------+

mysql&gt; <strong class="userinput"><code>SHOW BINLOG EVENTS;</code></strong>
+---------------+------+----------------+-----------+-------------+--------------------------------------------------------------------+
| Log_name      | Pos  | Event_type     | Server_id | End_log_pos | Info                                                               |
+---------------+------+----------------+-----------+-------------+--------------------------------------------------------------------+
| binlog.000001 |    4 | Format_desc    |         2 |         123 | Server ver: 8.0.22-log, Binlog ver: 4                              |
| binlog.000001 |  123 | Previous_gtids |         2 |         150 |                                                                    |
| binlog.000001 |  150 | Gtid           |         1 |         211 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:1'  |
| binlog.000001 |  211 | Query          |         1 |         270 | BEGIN                                                              |
| binlog.000001 |  270 | View_change    |         1 |         369 | view_id=14724832985483517:1                                        |
| binlog.000001 |  369 | Query          |         1 |         434 | COMMIT                                                             |
| binlog.000001 |  434 | Gtid           |         1 |         495 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:2'  |
| binlog.000001 |  495 | Query          |         1 |         585 | CREATE DATABASE test                                               |
| binlog.000001 |  585 | Gtid           |         1 |         646 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:3'  |
| binlog.000001 |  646 | Query          |         1 |         770 | use `test`; CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 TEXT NOT NULL) |
| binlog.000001 |  770 | Gtid           |         1 |         831 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:4'  |
| binlog.000001 |  831 | Query          |         1 |         890 | BEGIN                                                              |
| binlog.000001 |  890 | Table_map      |         1 |         933 | table_id: 108 (test.t1)                                            |
| binlog.000001 |  933 | Write_rows     |         1 |         975 | table_id: 108 flags: STMT_END_F                                    |
| binlog.000001 |  975 | Xid            |         1 |        1002 | COMMIT /* xid=30 */                                                |
| binlog.000001 | 1002 | Gtid           |         1 |        1063 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:5'  |
| binlog.000001 | 1063 | Query          |         1 |        1122 | BEGIN                                                              |
| binlog.000001 | 1122 | View_change    |         1 |        1261 | view_id=14724832985483517:2                                        |
| binlog.000001 | 1261 | Query          |         1 |        1326 | COMMIT                                                             |
+---------------+------+----------------+-----------+-------------+--------------------------------------------------------------------+
</pre><p>
          As seen above, the second server has been added to the group
          and it has replicated the changes from server s1
          automatically. In other words, the transactions applied on s1
          up to the point in time that s2 joined the group have been
          replicated to s2.
</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h5 class="title"><a name="group-replication-adding-additional-instances"></a>18.2.1.6.2 Adding Additional Instances</h5>

</div>

</div>

</div>
<a class="indexterm" name="idm46444259911904"></a><p>
          Adding additional instances to the group is essentially the
          same sequence of steps as adding the second server, except
          that the configuration has to be changed as it had to be for
          server s2. To summarise the required commands:
        </p><p>
          <span class="emphasis"><em>1. Create the configuration file</em></span>
        </p><pre data-lang="ini" class="programlisting">[mysqld]

#
# Disable other storage engines
#
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"

#
# Replication configuration parameters
#
server_id=3
gtid_mode=ON
enforce_gtid_consistency=ON
binlog_checksum=NONE

#
# Group Replication configuration
#
group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
group_replication_start_on_boot=off
group_replication_local_address= "s3:33061"
group_replication_group_seeds= "s1:33061,s2:33061,s3:33061"
group_replication_bootstrap_group= off</pre><p>
          <span class="emphasis"><em>2. Start the server and connect to it. Configure the
          distributed recovery credentials for the
          group_replication_recovery channel.</em></span>
        </p><pre data-lang="sql" class="programlisting">SET SQL_LOG_BIN=0;
CREATE USER <em class="replaceable"><code>rpl_user</code></em>@'%' IDENTIFIED BY '<em class="replaceable"><code>password</code></em>';
GRANT REPLICATION SLAVE ON *.* TO <em class="replaceable"><code>rpl_user</code></em>@'%';
GRANT BACKUP_ADMIN ON *.* TO <em class="replaceable"><code>rpl_user</code></em>@'%'; 
FLUSH PRIVILEGES;
SET SQL_LOG_BIN=1;
CHANGE MASTER TO MASTER_USER='<em class="replaceable"><code>rpl_user</code></em>', MASTER_PASSWORD='<em class="replaceable"><code>password</code></em>'  \\
FOR CHANNEL 'group_replication_recovery';</pre><p>
          <span class="emphasis"><em>4. Install the Group Replication plugin and start
          it.</em></span>
        </p><pre data-lang="sql" class="programlisting">INSTALL PLUGIN group_replication SONAME 'group_replication.so';
START GROUP_REPLICATION;</pre><p>
          At this point server s3 is booted and running, has joined the
          group and caught up with the other servers in the group.
          Consulting the
          <a class="link" href="performance-schema.html#replication-group-members-table" title="26.12.11.9 The replication_group_members Table"><code class="literal">performance_schema.replication_group_members</code></a>
          table again confirms this is the case.
        </p><pre data-lang="sql" class="programlisting">mysql&gt; SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+---------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE  |
+---------------------------+--------------------------------------+-------------+-------------+---------------+
| group_replication_applier | 395409e1-6dfa-11e6-970b-00212844f856 |   s1        |       3306  | ONLINE        |
| group_replication_applier | 7eb217ff-6df3-11e6-966c-00212844f856 |   s3        |       3306  | ONLINE        |
| group_replication_applier | ac39f1e6-6dfa-11e6-a69d-00212844f856 |   s2        |       3306  | ONLINE        |
+---------------------------+--------------------------------------+-------------+-------------+---------------+</pre><p>
          Issuing this same query on server s2 or server s1 yields the
          same result. Also, you can verify that server s3 has caught
          up:
        </p><pre data-lang="sql" class="programlisting">mysql&gt; <strong class="userinput"><code>SHOW DATABASES LIKE 'test';</code></strong>
+-----------------+
| Database (test) |
+-----------------+
| test            |
+-----------------+

mysql&gt; <strong class="userinput"><code>SELECT * FROM test.t1;</code></strong>
+----+------+
| c1 | c2   |
+----+------+
|  1 | Luis |
+----+------+

mysql&gt; <strong class="userinput"><code>SHOW BINLOG EVENTS;</code></strong>
+---------------+------+----------------+-----------+-------------+--------------------------------------------------------------------+
| Log_name      | Pos  | Event_type     | Server_id | End_log_pos | Info                                                               |
+---------------+------+----------------+-----------+-------------+--------------------------------------------------------------------+
| binlog.000001 |    4 | Format_desc    |         3 |         123 | Server ver: 8.0.22-log, Binlog ver: 4                              |
| binlog.000001 |  123 | Previous_gtids |         3 |         150 |                                                                    |
| binlog.000001 |  150 | Gtid           |         1 |         211 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:1'  |
| binlog.000001 |  211 | Query          |         1 |         270 | BEGIN                                                              |
| binlog.000001 |  270 | View_change    |         1 |         369 | view_id=14724832985483517:1                                        |
| binlog.000001 |  369 | Query          |         1 |         434 | COMMIT                                                             |
| binlog.000001 |  434 | Gtid           |         1 |         495 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:2'  |
| binlog.000001 |  495 | Query          |         1 |         585 | CREATE DATABASE test                                               |
| binlog.000001 |  585 | Gtid           |         1 |         646 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:3'  |
| binlog.000001 |  646 | Query          |         1 |         770 | use `test`; CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 TEXT NOT NULL) |
| binlog.000001 |  770 | Gtid           |         1 |         831 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:4'  |
| binlog.000001 |  831 | Query          |         1 |         890 | BEGIN                                                              |
| binlog.000001 |  890 | Table_map      |         1 |         933 | table_id: 108 (test.t1)                                            |
| binlog.000001 |  933 | Write_rows     |         1 |         975 | table_id: 108 flags: STMT_END_F                                    |
| binlog.000001 |  975 | Xid            |         1 |        1002 | COMMIT /* xid=29 */                                                |
| binlog.000001 | 1002 | Gtid           |         1 |        1063 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:5'  |
| binlog.000001 | 1063 | Query          |         1 |        1122 | BEGIN                                                              |
| binlog.000001 | 1122 | View_change    |         1 |        1261 | view_id=14724832985483517:2                                        |
| binlog.000001 | 1261 | Query          |         1 |        1326 | COMMIT                                                             |
| binlog.000001 | 1326 | Gtid           |         1 |        1387 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:6'  |
| binlog.000001 | 1387 | Query          |         1 |        1446 | BEGIN                                                              |
| binlog.000001 | 1446 | View_change    |         1 |        1585 | view_id=14724832985483517:3                                        |
| binlog.000001 | 1585 | Query          |         1 |        1650 | COMMIT                                                             |
+---------------+------+----------------+-----------+-------------+--------------------------------------------------------------------+
</pre>
</div>

</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="group-replication-deploying-locally"></a>18.2.2 Deploying Group Replication Locally</h3>

</div>

</div>

</div>
<p>
      

      The most common way to deploy Group Replication is using multiple
      server instances, to provide high availability. It is also
      possible to deploy Group Replication locally, for example for
      testing purposes. This section explains how you can deploy Group
      Replication locally.
</p>
<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Important
</div>
<p>
        Group Replication is usually deployed on multiple hosts because
        this ensures that high-availability is provided. The
        instructions in this section are not suitable for production
        deployments because all MySQL server instances are running on
        the same single host. In the event of failure of this host, the
        whole group fails. Therefore this information should be used for
        testing purposes and it should not be used in a production
        environments.
</p>
</div>
<p>
      This section explains how to create a replication group with three
      MySQL Server instances on one physical machine. This means that
      three data directories are needed, one per server instance, and
      that you need to configure each instance independently. This -
      procedure assumes that MySQL Server was downloaded and unpacked -
      into the directory named <code class="literal">mysql-8.0</code>. Each MySQL
      server instance requires a specific data directory. Create a
      directory named <code class="literal">data</code>, then in that directory
      create a subdirectory for each server instance, for example s1, s2
      and s3, and initialize each one.
    </p><pre data-lang="terminal" class="programlisting"><strong class="userinput"><code>mysql-8.0/bin/mysqld --initialize-insecure --basedir=$PWD/mysql-8.0 --datadir=$PWD/data/s1</code></strong>
<strong class="userinput"><code>mysql-8.0/bin/mysqld --initialize-insecure --basedir=$PWD/mysql-8.0 --datadir=$PWD/data/s2</code></strong>
<strong class="userinput"><code>mysql-8.0/bin/mysqld --initialize-insecure --basedir=$PWD/mysql-8.0 --datadir=$PWD/data/s3</code></strong>
</pre><p>
      Inside <code class="literal">data/s1</code>, <code class="literal">data/s2</code>,
      <code class="literal">data/s3</code> is an initialized data directory,
      containing the mysql system database and related tables and much
      more. To learn more about the initialization procedure, see
      <a class="xref" href="installing.html#data-directory-initialization" title="2.10.1 Initializing the Data Directory">Section 2.10.1, “Initializing the Data Directory”</a>.
</p>
<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Warning
</div>
<p>
        Do not use <code class="literal">-initialize-insecure</code> in production
        environments, it is only used here to simplify the tutorial. For
        more information on security settings, see
        <a class="xref" href="group-replication.html#group-replication-security" title="18.5 Group Replication Security">Section 18.5, “Group Replication Security”</a>.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h4 class="title"><a name="configure-local-group-members"></a>Configuration of Local Group Replication Members</h4>

</div>

</div>

</div>
<p>
        When you are following
        <a class="xref" href="group-replication.html#group-replication-configuring-instances" title="18.2.1.2 Configuring an Instance for Group Replication">Section 18.2.1.2, “Configuring an Instance for Group Replication”</a>, you
        need to add configuration for the data directories added in the
        previous section. For example:
      </p><pre data-lang="ini" class="programlisting">[mysqld]

# server configuration
datadir=&lt;full_path_to_data&gt;/data/s1
basedir=&lt;full_path_to_bin&gt;/mysql-8.0/

port=24801
socket=&lt;full_path_to_sock_dir&gt;/s1.sock</pre><p>
        These settings configure MySQL server to use the data directory
        created earlier and which port the server should open and start
        listening for incoming connections.
</p>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Note
</div>
<p>
          The non-default port of 24801 is used because in this tutorial
          the three server instances use the same hostname. In a setup
          with three different machines this would not be required.
</p>
</div>
<p>
        Group Replication requires a network connection between the
        members, which means that each member must be able to resolve
        the network address of all of the other members. For example in
        this tutorial all three instances run on one machine, so to
        ensure that the members can contact each other you could add a
        line to the option file such as
        <a class="link" href="replication.html#sysvar_report_host"><code class="literal">report_host=127.0.0.1</code></a>.
      </p><p>
        Then each member needs to be able to connect to the other
        members on their
        <a class="link" href="group-replication.html#sysvar_group_replication_local_address"><code class="literal">group_replication_local_address</code></a>.
        For example in the option file of member s1 add:
      </p><pre data-lang="ini" class="programlisting">group_replication_local_address= "127.0.0.1:24901"
group_replication_group_seeds= "127.0.0.1:24901,127.0.0.1:24902,127.0.0.1:24903"</pre><p>
        This configures s1 to use port 24901 for internal group
        communication with seed members. For each server instance you
        want to add to the group, make these changes in the option file
        of the member. For each member you must ensure a unique address
        is specified, so use a unique port per instance for
        <a class="link" href="group-replication.html#sysvar_group_replication_local_address"><code class="literal">group_replication_local_address</code></a>.
        Usually you want all members to be able to serve as seeds for
        members that are joining the group and have not got the
        transactions processed by the group. In this case, add all of
        the ports to
        <a class="link" href="group-replication.html#sysvar_group_replication_group_seeds"><code class="literal">group_replication_group_seeds</code></a>
        as shown above.
      </p><p>
        The remaining steps of
        <a class="xref" href="group-replication.html#group-replication-deploying-in-single-primary-mode" title="18.2.1 Deploying Group Replication in Single-Primary Mode">Section 18.2.1, “Deploying Group Replication in Single-Primary Mode”</a>
        apply equally to a group which you have deployed locally in this
        way.
</p>
</div>

</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a name="group-replication-monitoring"></a>18.3 Monitoring Group Replication</h2>

</div>

</div>

</div>
<div class="toc">
<dl class="toc"><dt><span class="section"><a href="group-replication.html#group-replication-server-states">18.3.1 Group Replication Server States</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-replication-group-members">18.3.2 The replication_group_members Table</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-replication-group-member-stats">18.3.3 The replication_group_member_stats Table</a></span></dt></dl>
</div>
<a class="indexterm" name="idm46444259852944"></a><p>
    Use the Perfomance Schema tables to monitor Group Replication,
    assuming that the
    <a class="ulink" href="performance-schema-quick-start" target="_top">Performance
    Schema</a> is enabled. Group Replication adds the following
    tables:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
        <a class="link" href="performance-schema.html#replication-group-member-stats-table" title="26.12.11.10 The replication_group_member_stats Table"><code class="literal">performance_schema.replication_group_member_stats</code></a>
      </p></li><li class="listitem"><p>
        <a class="link" href="performance-schema.html#replication-group-members-table" title="26.12.11.9 The replication_group_members Table"><code class="literal">performance_schema.replication_group_members</code></a>
</p></li></ul>
</div>
<p>
    These Perfomance Schema replication tables also show information
    about Group Replication:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
        <a class="link" href="performance-schema.html#replication-connection-status-table" title="26.12.11.2 The replication_connection_status Table"><code class="literal">performance_schema.replication_connection_status</code></a>
        shows information regarding Group Replication, for example the
        transactions that have been received from the group and queued
        in the applier queue (the relay log).
      </p></li><li class="listitem"><p>
        <a class="link" href="performance-schema.html#replication-applier-status-table" title="26.12.11.4 The replication_applier_status Table"><code class="literal">performance_schema.replication_applier_status</code></a>
        shows the state of the Group Replication related channels and
        threads If there are many different worker threads applying
        transactions, then the worker tables can also be used to monitor
        what each worker thread is doing.
</p></li></ul>
</div>
<p>
    The replication channels created by the Group Replication plugin are
    named:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
        <code class="literal">group_replication_recovery</code> - This channel is
        used for the replication changes that are related to the
        distributed recovery phase.
      </p></li><li class="listitem"><p>
        <code class="literal">group_replication_applier</code> - This channel is
        used for the incoming changes from the group. This is the
        channel used to apply transactions coming directly from the
        group.
</p></li></ul>
</div>
<p>
    The following sections describe how to interpret the information
    available.
</p>
<div class="section">

<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="group-replication-server-states"></a>18.3.1 Group Replication Server States</h3>
</div>
</div>
</div>
<a class="indexterm" name="idm46444259834368"></a><p>
      There are various states that a server instance can be in. If
      servers are communicating properly, all report the same states for
      all servers. However, if there is a network partition, or a server
      leaves the group, then different information could be reported,
      depending on which server is queried. If the server has left the
      group then it cannot report updated information about the other
      servers' states. If there is a partition, such that quorum is
      lost, servers are not able to coordinate between themselves. As a
      consequence, they cannot guess what the status of different
      servers is. Therefore, instead of guessing their state they report
      that some servers are unreachable.
</p>
<div class="table">
<a name="idm46444259831728"></a><p class="title"><b>Table 18.1 Server State</b></p>
<div class="table-contents">
<table><col width="38%"><col width="50%"><col width="12%"><thead><tr>
          <th scope="col"><p>
              Field
            </p></th>
          <th scope="col"><p>
              Description
            </p></th>
          <th scope="col"><p>
              Group Synchronized
            </p></th>
        </tr></thead><tbody><tr>
          <td scope="row"><p>
              <code class="literal">ONLINE</code>
            </p></td>
          <td><p>
              The member is ready to serve as a fully functional group
              member, meaning that the client can connect and start
              executing transactions.
            </p></td>
          <td><p>
              Yes
            </p></td>
        </tr><tr>
          <td scope="row"><p>
              <code class="literal">RECOVERING</code>
            </p></td>
          <td><p>
              The member is in the process of becoming an active member
              of the group and is currently going through the recovery
              process, receiving state transfer from a donor.
            </p></td>
          <td><p>
              No
            </p></td>
        </tr><tr>
          <td scope="row"><p>
              <code class="literal">OFFLINE</code>
            </p></td>
          <td><p>
              The Group Replication plugin is loaded but the member does
              not belong to any group.
            </p></td>
          <td><p>
              No
            </p></td>
        </tr><tr>
          <td scope="row"><p>
              <code class="literal">ERROR</code>
            </p></td>
          <td><p>
              The member is in an error state and is not functioning
              correctly as a group member. Depending on the exit action
              set by
              <a class="link" href="group-replication.html#sysvar_group_replication_exit_state_action"><code class="literal">group_replication_exit_state_action</code></a>,
              the member is in read-only mode
              (<a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only=ON</code></a>) and
              could also be in offline mode
              (<a class="link" href="server-administration.html#sysvar_offline_mode"><code class="literal">offline_mode=ON</code></a>). Note
              that a server in offline mode following the
              <code class="literal">OFFLINE_MODE</code> exit action is displayed
              with <code class="literal">ERROR</code> status, not
              <code class="literal">OFFLINE</code>. A server with the exit action
              <code class="literal">ABORT_SERVER</code> shuts down and is removed
              from the view of the group.
            </p></td>
          <td><p>
              No
            </p></td>
        </tr><tr>
          <td scope="row"><p>
              <code class="literal">UNREACHABLE</code>
            </p></td>
          <td><p>
              Whenever the local failure detector suspects that a given
              server is not reachable, because for example it was
              disconnected involuntarily, it shows that server's state
              as <code class="literal">UNREACHABLE</code>.
            </p></td>
          <td><p>
              No
            </p></td>
</tr></tbody></table>
</div>

</div>
<br class="table-break">
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="group-replication-replication-group-members"></a>18.3.2 The replication_group_members Table</h3>

</div>

</div>

</div>
<a class="indexterm" name="idm46444259791856"></a><p>
      The
      <a class="link" href="performance-schema.html#replication-group-members-table" title="26.12.11.9 The replication_group_members Table"><code class="literal">performance_schema.replication_group_members</code></a>
      table is used for monitoring the status of the different server
      instances that are members of the group. The information in the
      table is updated whenever there is a view change, for example when
      the configuration of the group is dynamically changed when a new
      member joins. At that point, servers exchange some of their
      metadata to synchronize themselves and continue to cooperate
      together. The information is shared between all the server
      instances that are members of the replication group, so
      information on all the group members can be queried from any
      member. This table can be used to get a high level view of the
      state of a replication group, for example by issuing:
    </p><pre data-lang="sql" class="programlisting"><strong class="userinput"><code>SELECT * FROM performance_schema.replication_group_members;</code></strong>
+---------------------------+--------------------------------------+--------------+-------------+--------------+-------------+----------------+
| CHANNEL_NAME              | MEMBER_ID	                           | MEMBER_HOST  | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION |
+---------------------------+--------------------------------------+--------------+-------------+--------------+-------------+----------------+
| group_replication_applier | 041f26d8-f3f3-11e8-adff-080027337932 | example1     |      3306   | ONLINE       | SECONDARY   | 8.0.13         |
| group_replication_applier | f60a3e10-f3f2-11e8-8258-080027337932 | example2     |      3306   | ONLINE       | PRIMARY     | 8.0.13         |
| group_replication_applier | fc890014-f3f2-11e8-a9fd-080027337932 | example3     |      3306   | ONLINE       | SECONDARY   | 8.0.13         |
+---------------------------+--------------------------------------+--------------+-------------+--------------+-------------+----------------+
</pre><p>
      Based on this result we can see that the group consists of three
      members, each member's host and port number which clients use to
      connect to the member, and the
      <a class="link" href="replication.html#sysvar_server_uuid"><code class="literal">server_uuid</code></a> of the member. The
      <code class="literal">MEMBER_STATE</code> column shows one of the
      <a class="xref" href="group-replication.html#group-replication-server-states" title="18.3.1 Group Replication Server States">Section 18.3.1, “Group Replication Server States”</a>, in this case it
      shows that all three members in this group are
      <code class="literal">ONLINE</code>, and the <code class="literal">MEMBER_ROLE</code>
      column shows that there are two secondaries, and a single primary.
      Therefore this group must be running in single-primary mode. The
      <code class="literal">MEMBER_VERSION</code> column can be useful when you
      are upgrading a group and are combining members running different
      MySQL versions. See
      <a class="xref" href="group-replication.html#group-replication-server-states" title="18.3.1 Group Replication Server States">Section 18.3.1, “Group Replication Server States”</a> for more
      information.
    </p><p>
      For more information about the <code class="literal">Member_host</code>
      value and its impact on the distributed recovery process, see
      <a class="xref" href="group-replication.html#group-replication-user-credentials" title="18.2.1.3 User Credentials">Section 18.2.1.3, “User Credentials”</a>.
</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="group-replication-replication-group-member-stats"></a>18.3.3 The replication_group_member_stats Table</h3>

</div>

</div>

</div>
<a class="indexterm" name="idm46444259775552"></a><p>
      Each member in a replication group certifies and applies
      transactions received by the group. Statistics regarding the
      certifier and applier procedures are useful to understand how the
      applier queue is growing, how many conflicts have been found, how
      many transactions were checked, which transactions are committed
      everywhere, and so on.
    </p><p>
      The
      <a class="link" href="performance-schema.html#replication-group-member-stats-table" title="26.12.11.10 The replication_group_member_stats Table"><code class="literal">performance_schema.replication_group_member_stats</code></a>
      table provides group-level information related to the
      certification process, and also statistics for the transactions
      received and originated by each individual member of the
      replication group. The information is shared between all the
      server instances that are members of the replication group, so
      information on all the group members can be queried from any
      member. Note that refreshing of statistics for remote members is
      controlled by the message period specified in the
      <a class="link" href="group-replication.html#sysvar_group_replication_flow_control_period"><code class="literal">group_replication_flow_control_period</code></a>
      option, so these can differ slightly from the locally collected
      statistics for the member where the query is made. To use this
      table to monitor a Group Replication member, issue:
    </p><pre data-lang="sql" class="programlisting">mysql&gt; <strong class="userinput"><code>SELECT * FROM performance_schema.replication_group_member_stats\G</code></strong></pre><p>
      These fields are important for monitoring the performance of the
      members connected in the group. For example, suppose that one of
      the group’s members always reports a large number of
      transactions in its queue compared to other members. This means
      that the member is delayed and is not able to keep up to date with
      the other members of the group. Based on this information, you
      could decide to either remove the member from the group, or delay
      the processing of transactions on the other members of the group
      in order to reduce the number of queued transactions. This
      information can also help you to decide how to adjust the flow
      control of the Group Replication plugin, see
      <a class="xref" href="group-replication.html#group-replication-flow-control" title="18.6.2 Flow Control">Section 18.6.2, “Flow Control”</a>.
</p>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a name="group-replication-operations"></a>18.4 Group Replication Operations</h2>

</div>

</div>

</div>
<div class="toc">
<dl class="toc"><dt><span class="section"><a href="group-replication.html#group-replication-configuring-online-group">18.4.1 Configuring an Online Group</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-consistency-guarantees">18.4.2 Transaction Consistency Guarantees</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-distributed-recovery">18.4.3 Distributed Recovery</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-network-partitioning">18.4.4 Network Partitioning</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-ipv6">18.4.5 Support For IPv6 And For Mixed IPv6 And IPv4 Groups</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-enterprise-backup">18.4.6 Using MySQL Enterprise Backup with Group Replication</a></span></dt></dl>
</div>
<a class="indexterm" name="idm46444259764576"></a><p>
    This section explains common operations for managing groups.
</p>
<div class="section">

<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="group-replication-configuring-online-group"></a>18.4.1 Configuring an Online Group</h3>

</div>

</div>

</div>

<div class="toc">
<dl class="toc"><dt><span class="section"><a href="group-replication.html#group-replication-changing-primary-member">18.4.1.1 Changing a Group's Primary Member</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-changing-group-mode">18.4.1.2 Changing a Group's Mode</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-group-write-consensus">18.4.1.3 Using Group Replication Group Write Consensus</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-communication-protocol">18.4.1.4 Setting a Group's Communication Protocol Version</a></span></dt></dl>
</div>
<a class="indexterm" name="idm46444259761392"></a><a class="indexterm" name="idm46444259759888"></a><p>
      You can configure an online group while Group Replication is
      running by using a set of UDFs, which rely on a group action
      coordinator. These UDFs are installed by the Group Replication
      plugin in version 8.0.13 and higher. This section describes how
      changes are made to a running group, and the available UDFs.
</p>
<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Important
</div>
<p>
        For the coordinator to be able to configure group wide actions
        on a running group, all members must be running MySQL 8.0.13 or
        higher and have the UDFs installed.
</p>
</div>
<p>
      To use the UDFs, connect to a member of the running group and
      issue the UDF with the <a class="link" href="sql-statements.html#select" title="13.2.10 SELECT Statement"><code class="literal">SELECT</code></a>
      statement. The Group Replication plugin processes the action and
      its parameters and the coordinator sends it to all members which
      are visible to the member where you issued the UDF. If the action
      is accepted, all members execute the action and send a termination
      message when completed. Once all members declare the action as
      finished, the invoking member returns the result to the client.
    </p><p>
      When configuring a whole group, the distributed nature of the
      operations means that they interact with many processes of the
      Group Replication plugin, and therefore you should observe the
      following:
    </p><p><b>You can issue configuration operations everywhere. </b>
        If you want to make member A the new primary you do not need to
        invoke the operation on member A. All operations are sent and
        executed in a coordinated way on all group members. Also, this
        distributed execution of an operation has a different
        ramification: if the invoking member dies, any already running
        configuration process continues to run on other members. In the
        unlikely event that the invoking member dies, you can still use
        the monitoring features to ensure other members complete the
        operation successfully.
      </p><p><b>All members must be online. </b>
        To simplify the migration or election processes and guarantee
        they are as fast as possible, the group must not contain any
        member currently in the distributed recovery process, otherwise
        the configuration action is rejected by the member where you
        issue the statement.
      </p><p><b>No members can join a group during a configuration change. </b>
        Any member that attempts to join the group during a coordinated
        configuration change leaves the group and cancels its join
        process.
      </p><p><b>Only one configuration at once. </b>
        A group which is executing a configuration change cannot accept
        any other group configuration change, because concurrent
        configuration operations could lead to member divergence.
      </p><p><b>All members must be running MySQL 8.0.13 or higher. </b>
        Due to the distributed nature of the configuration actions, all
        members must recognize them in order to execute them. The
        operation is therefore rejected if any server running MySQL
        Server version 8.0.12 or lower is present in the group.
</p>
<div class="section">

<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="group-replication-changing-primary-member"></a>18.4.1.1 Changing a Group's Primary Member</h4>
</div>
</div>
</div>
<a class="indexterm" name="idm46444259745008"></a><p>
        This section explains how to change which member of a
        single-primary group is the primary. The function used to change
        a group's mode can be run on any member.
</p>
<div class="simplesect">

<div class="titlepage">
<div>

<div class="simple">
<h5 class="title"><a name="group-replication-change-primary"></a>Changing which Member is Primary</h5>
</div>
</div>
</div>
<a class="indexterm" name="idm46444259741856"></a><a class="indexterm" name="idm46444259740352"></a><a class="indexterm" name="idm46444259739264"></a><a class="indexterm" name="idm46444259737808"></a><p>
          Use the
          <a class="link" href="sql-statements.html#udf_group-replication-set-as-primary"><code class="literal">group_replication_set_as_primary()</code></a>
          UDF to change which member is the primary in a single-primary
          group. This function has no effect if issued on a member of a
          multi-primary group. Only a primary member can write to the
          group, so if an asynchronous channel is running on that
          member, no switch is allowed until the asynchronous channel is
          stopped.
        </p><p>
          If you issue the UDF on a member running a MySQL Server
          version from 8.0.17, and all members are running MySQL Server
          version 8.0.17 or higher, you can only specify a new primary
          member that is running the lowest MySQL Server version in the
          group, based on the patch version. This safeguard is applied
          to ensure the group maintains compatibility with new
          functions. If any member is running a MySQL Server version
          between MySQL 8.0.13 and MySQL 8.0.16, this safeguard is not
          enforced for the group and you can specify any new primary
          member, but it is recommended to select a primary that is
          running the lowest MySQL Server version in the group.
        </p><p>
          Pass in the <a class="link" href="replication.html#sysvar_server_uuid"><code class="literal">server_uuid</code></a> of
          the member which you want to become the new primary of the
          group by issuing:
        </p><pre data-lang="sql" class="programlisting"><strong class="userinput"><code>SELECT group_replication_set_as_primary(member_uuid);</code></strong>
</pre><p>
          While the action runs, you can check its progress by issuing:
        </p><pre data-lang="sql" class="programlisting"><strong class="userinput"><code>SELECT event_name, work_completed, work_estimated FROM performance_schema.events_stages_current WHERE event_name LIKE "%stage/group_rpl%";</code></strong>
+----------------------------------------------------------------------------------+----------------+----------------+
| event_name                                                                       | work_completed | work_estimated |
+----------------------------------------------------------------------------------+----------------+----------------+
| stage/group_rpl/Primary Election: Waiting for members to turn on super_read_only |              3 |              5 |
+----------------------------------------------------------------------------------+----------------+----------------+
</pre>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="group-replication-changing-group-mode"></a>18.4.1.2 Changing a Group's Mode</h4>

</div>

</div>

</div>
<a class="indexterm" name="idm46444259725776"></a><p>
        This section explains how to change the mode which a group is
        running in, either single or multi-primary. The functions used
        to change a group's mode can be run on any member.
</p>
<div class="simplesect">

<div class="titlepage">
<div>

<div class="simple">
<h5 class="title"><a name="group-replication-switch-to-single"></a>Changing to Single-Primary Mode</h5>
</div>
</div>
</div>
<a class="indexterm" name="idm46444259722592"></a><a class="indexterm" name="idm46444259721088"></a><a class="indexterm" name="idm46444259719984"></a><a class="indexterm" name="idm46444259718528"></a><p>
          Use the
          <a class="link" href="sql-statements.html#udf_group-replication-switch-to-single-primary-mode"><code class="literal">group_replication_switch_to_single_primary_mode()</code></a>
          UDF to change a group running in multi-primary mode to
          single-primary mode by issuing:
        </p><pre data-lang="sql" class="programlisting"><strong class="userinput"><code>SELECT group_replication_switch_to_single_primary_mode()</code></strong>
</pre><p>
          When you change to single-primary mode, strict consistency
          checks are also disabled on all group members, as required in
          single-primary mode
          (<a class="link" href="group-replication.html#sysvar_group_replication_enforce_update_everywhere_checks"><code class="literal">group_replication_enforce_update_everywhere_checks=OFF</code></a>).
        </p><p>
          If no string is passed in, the election of the new primary in
          the resulting single-primary group follows the election
          policies described in
          <a class="xref" href="group-replication.html#group-replication-single-primary-mode" title="18.1.3.1 Single-Primary Mode">Section 18.1.3.1, “Single-Primary Mode”</a>. To
          override the election process and configure a specific member
          of the multi-primary group as the new primary in the process,
          get the <a class="link" href="replication.html#sysvar_server_uuid"><code class="literal">server_uuid</code></a> of the
          member and pass it to <a class="link" href="sql-statements.html#udf_group-replication-switch-to-single-primary-mode"><code class="literal">
          group_replication_switch_to_single_primary_mode()</code></a>.
          For example issue:
        </p><pre data-lang="sql" class="programlisting"><strong class="userinput"><code>SELECT group_replication_switch_to_single_primary_mode(<em class="replaceable"><code>member_uuid</code></em>);</code></strong>
</pre><p>
          If you issue the UDF on a member running a MySQL Server
          version from 8.0.17, and all members are running MySQL Server
          version 8.0.17 or higher, you can only specify a new primary
          member that is running the lowest MySQL Server version in the
          group, based on the patch version. This safeguard is applied
          to ensure the group maintains compatibility with new
          functions. If you do not specify a new primary member, the
          election process considers the patch version of the group
          members.
        </p><p>
          If any member is running a MySQL Server version between MySQL
          8.0.13 and MySQL 8.0.16, this safeguard is not enforced for
          the group and you can specify any new primary member, but it
          is recommended to select a primary that is running the lowest
          MySQL Server version in the group. If you do not specify a new
          primary member, the election process considers only the major
          version of the group members.
        </p><p>
          While the action runs, you can check its progress by issuing:
        </p><pre data-lang="sql" class="programlisting"><strong class="userinput"><code>SELECT event_name, work_completed, work_estimated FROM performance_schema.events_stages_current WHERE event_name LIKE "%stage/group_rpl%";</code></strong>
+----------------------------------------------------------------------------+----------------+----------------+
| event_name                                                                 | work_completed | work_estimated |
+----------------------------------------------------------------------------+----------------+----------------+
| stage/group_rpl/Primary Switch: waiting for pending transactions to finish |              4 |             20 |
+----------------------------------------------------------------------------+----------------+----------------+
</pre>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h5 class="title"><a name="group-replication-switch-to-multi"></a>Changing to Multi-Primary Mode</h5>

</div>

</div>

</div>
<a class="indexterm" name="idm46444259699872"></a><a class="indexterm" name="idm46444259698368"></a><a class="indexterm" name="idm46444259697264"></a><a class="indexterm" name="idm46444259695808"></a><p>
          Use the
          <a class="link" href="sql-statements.html#udf_group-replication-switch-to-multi-primary-mode"><code class="literal">group_replication_switch_to_multi_primary_mode()</code></a>
          UDF to change a group running in single-primary mode to
          multi-primary mode by issuing:
        </p><pre data-lang="sql" class="programlisting"><strong class="userinput"><code>SELECT group_replication_switch_to_multi_primary_mode()</code></strong>
</pre><p>
          After some coordinated group operations to ensure the safety
          and consistency of your data, all members which belong to the
          group become primaries.
        </p><p>
          When you change a group that was running in single-primary
          mode to run in multi-primary mode, members running MySQL
          8.0.17 or higher are automatically placed in read-only mode if
          they are running a higher MySQL server version than the lowest
          version present in the group. Members running MySQL 8.0.16 or
          lower do not carry out this check, and are always placed in
          read-write mode.
        </p><p>
          While the action runs, you can check its progress by issuing:
        </p><pre data-lang="sql" class="programlisting">SELECT event_name, work_completed, work_estimated FROM performance_schema.events_stages_current WHERE event_name LIKE "%stage/group_rpl%";
+----------------------------------------------------------------------+----------------+----------------+
| event_name                                                           | work_completed | work_estimated |
+----------------------------------------------------------------------+----------------+----------------+
| stage/group_rpl/Multi-primary Switch: applying buffered transactions |              0 |              1 |
+----------------------------------------------------------------------+----------------+----------------+</pre>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="group-replication-group-write-consensus"></a>18.4.1.3 Using Group Replication Group Write Consensus</h4>

</div>

</div>

</div>
<a class="indexterm" name="idm46444259686016"></a><a class="indexterm" name="idm46444259684528"></a><p>
        This section explains how to inspect and configure the maximum
        number of consensus instances at any time for a group. This
        maximum is referred to as the event horizon for a group, and is
        the maximum number of consensus instances that the group can
        execute in parallel. This enables you to fine tune the
        performance of your Group Replication deployment. For example,
        the default value of 10 is suitable for a group running on a
        LAN, but for groups operating over a slower network such as a
        WAN, increase this number to improve performance.
</p>
<div class="simplesect">

<div class="titlepage">
<div>

<div class="simple">
<h5 class="title"><a name="group-replication-inspect-write-concurrency"></a>Inspecting a Group's Write Concurrency</h5>
</div>
</div>
</div>
<a class="indexterm" name="idm46444259681184"></a><a class="indexterm" name="idm46444259679680"></a><a class="indexterm" name="idm46444259678640"></a><a class="indexterm" name="idm46444259677184"></a><p>
          Use the
          <a class="link" href="sql-statements.html#udf_group-replication-get-write-concurrency"><code class="literal">group_replication_get_write_concurrency()</code></a>
          UDF to inspect a group's event horizon value at runtime by
          issuing:
        </p><pre data-lang="sql" class="programlisting"><strong class="userinput"><code>SELECT group_replication_get_write_concurrency();</code></strong>
</pre>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h5 class="title"><a name="group-replication-configure-write-concurrency"></a>Configuring a Group's Write Concurrency</h5>

</div>

</div>

</div>
<a class="indexterm" name="idm46444259670976"></a><a class="indexterm" name="idm46444259669472"></a><a class="indexterm" name="idm46444259668432"></a><a class="indexterm" name="idm46444259666976"></a><p>
          Use the
          <a class="link" href="sql-statements.html#udf_group-replication-set-write-concurrency"><code class="literal">group_replication_set_write_concurrency()</code></a>
          UDF to set the maximum number of consensus instances that the
          system can execute in parallel by issuing:
        </p><pre data-lang="sql" class="programlisting"><strong class="userinput"><code>SELECT group_replication_set_write_concurrency(<em class="replaceable"><code>instances</code></em>);</code></strong>
</pre><p>
          where <em class="replaceable"><code>instances</code></em> is the new maximum
          number of consensus instances. The
          <a class="link" href="security.html#priv_group-replication-admin"><code class="literal">GROUP_REPLICATION_ADMIN</code></a>
          privilege is required to use this UDF.
</p>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="group-replication-communication-protocol"></a>18.4.1.4 Setting a Group's Communication Protocol Version</h4>

</div>

</div>

</div>
<a class="indexterm" name="idm46444259658000"></a><p>
        From MySQL 8.0.16, Group Replication has the concept of a
        communication protocol for the group. The Group Replication
        communication protocol version can be managed explicitly, and
        set to accommodate the oldest MySQL Server version that you want
        the group to support. This enables groups to be formed from
        members at different MySQL Server versions while ensuring
        backward compatibility. Versions from MySQL 5.7.14 allow
        compression of messages, and versions from MySQL 8.0.16 also
        allow fragmentation of messages. All members of the group must
        use the same communication protocol version, so that group
        members can be at different MySQL Server releases but only send
        messages that can be understood by all group members.
      </p><p>
        A MySQL server at version X can only join and reach
        <code class="literal">ONLINE</code> status in a replication group if the
        group's communication protocol version is less than or equal to
        X. When a new member joins a replication group, it checks the
        communication protocol version that is announced by the existing
        members of the group. If the joining member supports that
        version, it joins the group and uses the communication protocol
        that the group has announced, even if the member supports
        additional communication capabilities. If the joining member
        does not support the communication protocol version, it is
        expelled from the group.
      </p><p>
        If two members attempt to join in the same membership change
        event, they can only join if the communication protocol version
        for both members is already compatible with the group's
        communication protocol version. Members with different
        communication protocol versions from the group must join in
        isolation. For example:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            One MySQL Server 8.0.16 instance can successfully join a
            group that uses the communication protocol version 5.7.24.
          </p></li><li class="listitem"><p>
            One MySQL Server 5.7.24 instance cannot successfully join a
            group that uses the communication protocol version 8.0.16.
          </p></li><li class="listitem"><p>
            Two MySQL Server 8.0.16 instances cannot simultaneously join
            a group that uses the communication protocol version 5.7.24.
          </p></li><li class="listitem"><p>
            Two MySQL Server 8.0.16 instances can simultaneously join a
            group that uses the communication protocol version 8.0.16.
</p></li></ul>
</div>
<p>
        You can inspect the communication protocol in use by a group by
        using the
        <a class="link" href="sql-statements.html#udf_group-replication-get-communication-protocol"><code class="literal">group_replication_get_communication_protocol()</code></a>
        UDF, which returns the oldest MySQL Server version that the
        group supports. All existing members of the group return the
        same communication protocol version. For example:
      </p><pre data-lang="sql" class="programlisting">SELECT group_replication_get_communication_protocol();
+------------------------------------------------+
| group_replication_get_communication_protocol() |
+------------------------------------------------+
| 8.0.16                                         |
+------------------------------------------------+</pre><p>
        Note that the
        <a class="link" href="sql-statements.html#udf_group-replication-get-communication-protocol"><code class="literal">group_replication_get_communication_protocol()</code></a>
        UDF returns the minimum MySQL version that the group supports,
        which might differ from the version number that was passed to
        the
        <a class="link" href="sql-statements.html#udf_group-replication-set-communication-protocol"><code class="literal">group_replication_set_communication_protocol()</code></a>
        UDF, and from the MySQL Server version that is installed on the
        member where you use the UDF.
      </p><p>
        If you need to change the communication protocol version of a
        group so that members at earlier releases can join, use the
        <a class="link" href="sql-statements.html#udf_group-replication-set-communication-protocol"><code class="literal">group_replication_set_communication_protocol()</code></a>
        UDF to specify the MySQL Server version of the oldest member
        that you want to allow. This makes the group fall back to a
        compatible communication protocol version if possible. The
        <a class="link" href="security.html#priv_group-replication-admin"><code class="literal">GROUP_REPLICATION_ADMIN</code></a> privilege
        is required to use this UDF, and all existing group members must
        be online when you issue the statement, with no loss of
        majority. For example:
      </p><pre data-lang="sql" class="programlisting"><strong class="userinput"><code>SELECT group_replication_set_communication_protocol("5.7.25");</code></strong>
</pre><p>
        If you upgrade all the members of a replication group to a new
        MySQL Server release, the group's communication protocol version
        is not automatically upgraded to match. If you no longer need to
        support members at earlier releases, you can use the
        <a class="link" href="sql-statements.html#udf_group-replication-set-communication-protocol"><code class="literal">group_replication_set_communication_protocol()</code></a>
        UDF to set the communication protocol version to the new MySQL
        Server version to which you have upgraded the members. For
        example:
      </p><pre data-lang="sql" class="programlisting"><strong class="userinput"><code>SELECT group_replication_set_communication_protocol("8.0.16");</code></strong>
</pre><p>
        The
        <a class="link" href="sql-statements.html#udf_group-replication-set-communication-protocol"><code class="literal">group_replication_set_communication_protocol()</code></a>
        UDF is implemented as a group action, so it is executed at the
        same time on all members of the group. The group action starts
        buffering messages and waits for delivery of any outgoing
        messages that were already in progress to complete, then changes
        the communication protocol version and sends the buffered
        messages. If a member attempts to join the group at any time
        after you change the communication protocol version, the group
        members announce the new protocol version.
      </p><p>
        MySQL InnoDB cluster automatically and transparently manages the
        communication protocol versions of its members, whenever the
        cluster topology is changed using AdminAPI operations. An InnoDB
        cluster always uses the most recent communication protocol
        version that is supported by all the instances that are
        currently part of the cluster or joining it. For details, see
        <a class="xref" href="mysql-innodb-cluster-userguide.html#innodb-cluster-group-replication-protocol" title="InnoDB cluster and Group Replication Protocol">InnoDB cluster and Group Replication Protocol</a>.
</p>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="group-replication-consistency-guarantees"></a>18.4.2 Transaction Consistency Guarantees</h3>

</div>

</div>

</div>
<div class="toc">
<dl class="toc"><dt><span class="section"><a href="group-replication.html#group-replication-understanding-consistency-guarantees">18.4.2.1 Understanding Transaction Consistency Guarantees</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-configuring-consistency-guarantees">18.4.2.2 Configuring Transaction Consistency Guarantees</a></span></dt></dl>
</div>
<a class="indexterm" name="idm46444259628144"></a><p>
      One of the major implications of a distributed system such as
      Group Replication is the consistency guarantees that it provides
      as a group. In other words, the consistency of the global
      synchronization of transactions distributed across the members of
      the group. This section describes how Group Replication handles
      consistency guarantees depending on the events that occur in a
      group, and how to best configure your group's consistency
      guarantees.
</p>
<div class="section">

<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="group-replication-understanding-consistency-guarantees"></a>18.4.2.1 Understanding Transaction Consistency Guarantees</h4>
</div>
</div>
</div>
<a class="indexterm" name="idm46444259624624"></a><a class="indexterm" name="idm46444259623104"></a><p>
        In terms of distributed consistency guarantees, either in normal
        or failure repair operations, Group Replication has always been
        an eventual consistency system. This means that as soon as the
        incoming traffic slows down or stops, all group members have the
        same data content. The events that relate to the consistency of
        a system can be split into control operations, either manual or
        automatically triggered by failures; and data flow operations.
      </p><p>
        For Group Replication, the control operations that can be
        evaluated in terms of consistency are:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            a member joining or leaving, which is covered by Group
            Replication's
            <a class="xref" href="group-replication.html#group-replication-distributed-recovery" title="18.4.3 Distributed Recovery">Section 18.4.3, “Distributed Recovery”</a> and
            write protection.

            
          </p></li><li class="listitem"><p>
            network failures, which are covered by the fencing modes.
          </p></li><li class="listitem"><p>
            in single-primary groups, primary failover, which can also
            be an operation triggered by
            <a class="link" href="sql-statements.html#udf_group-replication-set-as-primary"><code class="literal">group_replication_set_as_primary()</code></a>.
</p></li></ul>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h5 class="title"><a name="group-replication-control-operation-failover"></a>Consistency Guarantees and Primary Failover</h5>

</div>

</div>

</div>
<a class="indexterm" name="idm46444259613200"></a><a class="indexterm" name="idm46444259611712"></a><p>
          

          In a single-primary group, in the event of a primary failover
          when a secondary is promoted to primary, the new primary can
          either be made available to application traffic immediately,
          regardless of how large the replication backlog is, or
          alternatively access to it can be restricted until the backlog
          has been applied.
        </p><p>
          With the first approach, the group takes the minimum time
          possible to secure a stable group membership after a primary
          failure by electing a new primary and then allowing data
          access immediately while it is still applying any possible
          backlog from the old primary. Write consistency is ensured,
          but reads can temporarily retrieve stale data while the new
          primary applies the backlog. For example, if client C1 wrote
          <code class="literal">A=2 WHERE A=1</code> on the old primary just
          before its failure, when client C1 is reconnected to the new
          primary it could potentially read <code class="literal">A=1</code> until
          the new primary applies its backlog and catches up with the
          state of the old primary before it left the group.
        </p><p>
          With the second alternative, the system secures a stable group
          membership after the primary failure and elects a new primary
          in the same way as the first alternative, but in this case the
          group then waits until the new primary applies all backlog and
          only then does it permit data access. This ensures that in a
          situation as described previously, when client C1 is
          reconnected to the new primary it reads
          <code class="literal">A=2</code>. However, the trade-off is that the
          time required to failover is then proportional to the size of
          the backlog, which on a correctly configured group should be
          small

          

          .
        </p><p>
          Prior to MySQL 8.0.14 there was no way to configure the
          failover policy, by default availability was maximized as
          described in the first approach. In a group with members
          running MySQL 8.0.14 and higher, you can configure the level
          of transaction consistency guarantees provided by members
          during primary failover using the
          <a class="link" href="group-replication.html#sysvar_group_replication_consistency"><code class="literal">group_replication_consistency</code></a>
          variable. See
          <a class="xref" href="group-replication.html#group-replication-consistency-level-impact-election" title="Impact of Consistency on Primary Election">Impact of Consistency on Primary Election</a>.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h5 class="title"><a name="group-replication-data-flow-operations"></a>Data Flow Operations</h5>

</div>

</div>

</div>
<a class="indexterm" name="idm46444259599200"></a><p>
          Data flow is relevant to group consistency guarantees due to
          the reads and writes executed against a group, especially when
          these operations are distributed across all members. Data flow
          operations apply to both modes of Group Replication:
          single-primary and multi-primary, however to make this
          explanation clearer it is restricted to single-primary mode.
          The usual way to split incoming read or write transactions
          across a single-primary group's members is to route writes to
          the primary and evenly distribute reads to the secondaries.
          Since the group should behave as a single entity, it is
          reasonable to expect that writes on the primary are
          instantaneously available on the secondaries. Although Group
          Replication is written using Group Communication System (GCS)
          protocols that implement the Paxos algorithm, some parts of
          Group Replication are asynchronous, which implies that data is
          asynchronously applied to secondaries. This means that a
          client C2 can write <code class="literal">B=2 WHERE B=1</code> on the
          primary, immediately connect to a secondary and read
          <code class="literal">B=1</code>. This is because the secondary is still
          applying backlog, and has not applied the transaction which
          was applied by the primary.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h5 class="title"><a name="group-replication-synchronization-points"></a>Transaction Synchronization Points</h5>

</div>

</div>

</div>
<a class="indexterm" name="idm46444259593120"></a><p>
          You configure a group's consistency guarantee based on the
          point at which you want to synchronize transactions across the
          group. To help you understand the concept, this section
          simplifies the points of synchronizing transactions across a
          group to be at the time of a read operation or at the time of
          a write operation. If data is synchronized at the time of a
          read, the current client session waits until a given
          point, which is the point in time that all preceding update
          transactions have been applied, before it can start executing.
          With this approach, only this session is affected, all other
          concurrent data operations are not affected.
        </p><p>
          If data is synchronized at the time of write, the writing
          session waits until all secondaries have written their data.
          Group Replication uses a total order on writes, and therefore
          this implies waiting for this and all preceding writes that
          are in secondaries’ queues to be applied. Therefore when
          using this synchronization point, the writing session waits
          for all secondaries queues to be applied.
        </p><p>
          Any alternative ensures that in the situation described for
          client C2 would always read <code class="literal">B=2</code> even if
          immediately connected to a secondary. Each alternative has its
          advantages and disadvantages, which are directly related to
          your system workload. The following examples describe
          different types of workloads and advise which point of
          synchronization is appropriate.
        </p><p>
          Imagine the following situations:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              you want to load balance your reads without deploying
              additional restrictions on which server you read from to
              avoid reading stale data, group writes are much less
              common than group reads.
            </p></li><li class="listitem"><p>
              you have a group that has a predominantly read-only data,
              you want read-write transactions to be applied everywhere
              once they commit, so that subsequent reads are done on
              up-to-date data that includes the latest write. This
              ensures that you do not pay the synchronization cost for
              every RO transaction, but only on RW ones.
</p></li></ul>
</div>
<p>
          In these cases, you should choose to synchronize on writes.
        </p><p>
          Imagine the following situations:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              you want to load balance your reads without deploying
              additional restrictions on which server you read from to
              avoid reading stale data, group writes are much more
              common than group reads.
            </p></li><li class="listitem"><p>
              you want specific transactions in your workload to always
              read up-to-date data from the group, for example whenever
              sensitive data is updated (such as credentials for a file
              or similar data) and you want to enforce that reads
              retrieve the most up to date value.
</p></li></ul>
</div>
<p>
          In these cases, you should choose to synchronize on reads.
</p>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="group-replication-configuring-consistency-guarantees"></a>18.4.2.2 Configuring Transaction Consistency Guarantees</h4>

</div>

</div>

</div>
<a class="indexterm" name="idm46444259578336"></a><p>
        Although the
        <a class="xref" href="group-replication.html#group-replication-synchronization-points" title="Transaction Synchronization Points">Transaction Synchronization Points</a>
        section explains that conceptually there are two synchronization
        points from which you can choose: on read or on write, these
        terms were a simplification and the terms used in Group
        Replication are: <span class="emphasis"><em>before</em></span> and
        <span class="emphasis"><em>after</em></span> transaction execution. The
        consistency level can have a different impact on read-only (RO)
        and read-write (RW) transactions processed by the group as
        demonstrated in this section.
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p><a class="xref" href="group-replication.html#group-replication-choose-consistency-level" title="How to Choose a Consistency Level">How to Choose a Consistency Level</a></p></li><li class="listitem"><p><a class="xref" href="group-replication.html#group-replication-consistency-level-impacts" title="Impacts of Consistency Levels">Impacts of Consistency Levels</a></p></li><li class="listitem"><p><a class="xref" href="group-replication.html#group-replication-consistency-level-impact-election" title="Impact of Consistency on Primary Election">Impact of Consistency on Primary Election</a></p></li></ul>
</div>
<p>
        The following list shows the possible consistency levels that
        you can configure in Group Replication using the
        <a class="link" href="group-replication.html#sysvar_group_replication_consistency"><code class="literal">group_replication_consistency</code></a>
        variable, in order of increasing transaction consistency
        guarantee:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            <code class="literal">EVENTUAL</code>
          </p><p>
            Both RO and RW transactions do not wait for preceding
            transactions to be applied before executing. This was the
            behavior of Group Replication before the
            <a class="link" href="group-replication.html#sysvar_group_replication_consistency"><code class="literal">group_replication_consistency</code></a>
            variable was added. A RW transaction does not wait for other
            members to apply a transaction. This means that a
            transaction could be externalized on one member before the
            others. This also means that in the event of a primary
            failover, the new primary can accept new RO and RW
            transactions before the previous primary transactions are
            all applied. RO transactions could result in outdated
            values, RW transactions could result in a rollback due to
            conflicts.
          </p></li><li class="listitem"><p>
            <code class="literal">BEFORE_ON_PRIMARY_FAILOVER</code>
          </p><p>
            New RO or RW transactions with a newly elected primary that
            is applying backlog from the old primary are held (not
            applied) until any backlog has been applied. This ensures
            that when a primary failover happens, intentionally or not,
            clients always see the latest value on the primary. This
            guarantees consistency, but means that clients must be able
            to handle the delay in the event that a backlog is being
            applied. Usually this delay should be minimal, but it does
            depend on the size of the backlog.
          </p></li><li class="listitem"><p>
            <code class="literal">BEFORE</code>
          </p><p>
            A RW transaction waits for all preceding transactions to
            complete before being applied. A RO transaction waits for
            all preceding transactions to complete before being
            executed. This ensures that this transaction reads the
            latest value by only affecting the latency of the
            transaction. This reduces the overhead of synchronization on
            every RW transaction, by ensuring synchronization is used
            only on RO transactions. This consistency level also
            includes the consistency guarantees provided by
            <code class="literal">BEFORE_ON_PRIMARY_FAILOVER</code>.
          </p></li><li class="listitem"><p>
            <code class="literal">AFTER</code>
          </p><p>
            A RW transaction waits until its changes have been applied
            to all of the other members. This value has no effect on RO
            transactions. This mode ensures that when a transaction is
            committed on the local member, any subsequent transaction
            reads the written value or a more recent value on any group
            member. Use this mode with a group that is used for
            predominantly RO operations to ensure that applied RW
            transactions are applied everywhere once they commit. This
            could be used by your application to ensure that subsequent
            reads fetch the latest data which includes the latest
            writes. This reduces the overhead of synchronization on
            every RO transaction, by ensuring synchronization is used
            only on RW transactions. This consistency level also
            includes the consistency guarantees provided by
            <code class="literal">BEFORE_ON_PRIMARY_FAILOVER</code>.
          </p></li><li class="listitem"><p>
            <code class="literal">BEFORE_AND_AFTER</code>
          </p><p>
            A RW transaction waits for 1) all preceding transactions to
            complete before being applied and 2) until its changes have
            been applied on other members. A RO transaction waits for
            all preceding transactions to complete before execution
            takes place. This consistency level also includes the
            consistency guarantees provided by
            <code class="literal">BEFORE_ON_PRIMARY_FAILOVER</code>.
</p></li></ul>
</div>
<p>
        The <code class="literal">BEFORE</code> and
        <code class="literal">BEFORE_AND_AFTER</code> consistency levels can be
        both used on RO and RW transactions. The
        <code class="literal">AFTER</code> consistency level has no impact on RO
        transactions, because they do not generate changes.
</p>
<div class="simplesect">

<div class="titlepage">
<div>

<div class="simple">
<h5 class="title"><a name="group-replication-choose-consistency-level"></a>How to Choose a Consistency Level</h5>
</div>
</div>
</div>
<a class="indexterm" name="idm46444259548352"></a><p>
          The different consistency levels provide flexibility to both
          DBAs, who can use them to set up their infrastructure; and to
          developers who can use the consistency level that best suits
          their application's requirements. The following scenarios show
          how to choose a consistency guarantee level based on how you
          use your group:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              <span class="emphasis"><em>Scenario 1</em></span> you want to load balance
              your reads without worrying about stale reads, your group
              write operations are considerably fewer than your group
              read operations. In this case, you should choose
              <code class="literal">AFTER</code>.
            </p></li><li class="listitem"><p>
              <span class="emphasis"><em>Scenario 2</em></span> you have a data set that
              applies a lot of writes and you want to do occasional
              reads without having to worry about reading stale data. In
              this case, you should choose <code class="literal">BEFORE</code>.
            </p></li><li class="listitem"><p>
              <span class="emphasis"><em>Scenario 3</em></span> you want specific
              transactions in your workload to always read up-to-date
              data from the group, so that whenever that sensitive data
              is updated (such as credentials for a file or similar
              data) you want to enforce that reads always read the most
              up to date value. In this case, you should choose
              <code class="literal">BEFORE</code>.
            </p></li><li class="listitem"><p>
              <span class="emphasis"><em>Scenario 4</em></span> you have a group that has
              predominantly read-only (RO) data, you want your
              read-write (RW) transactions to be applied everywhere once
              they commit, so that subsequent reads are done on
              up-to-date data that includes your latest writes and you
              do not pay the synchronization on every RO transaction,
              but only on RW ones. In this case, you should choose
              <code class="literal">AFTER</code>.
            </p></li><li class="listitem"><p>
              <span class="emphasis"><em>Scenario 5</em></span> you have a group that has
              predominantly read-only data, you want your read-write
              (RW) transactions to always read up-to-date data from the
              group and to be applied everywhere once they commit, so
              that subsequent reads are done on up-to-date data that
              includes your latest write and you do not pay the
              synchronization on every read-only (RO) transaction, but
              only on RW ones. In this case, you should choose
              <code class="literal">BEFORE_AND_AFTER</code>.
</p></li></ul>
</div>
<p>
          You have the freedom to choose the scope at which the
          consistency level is enforced. This is important because
          consistency levels could have a negative impact on group
          performance if you set them at a global scope. Therefore you
          can configure the consistency level of a group by using the
          <a class="link" href="group-replication.html#sysvar_group_replication_consistency"><code class="literal">group_replication_consistency</code></a>
          system variable at different scopes.
        </p><p>
          To enforce the consistency level on the current session, use
          the session scope:
        </p><pre data-lang="sql" class="programlisting">&gt; SET @@SESSION.group_replication_consistency= 'BEFORE';</pre><p>
          To enforce the consistency level on all sessions, use the
          global scope:
        </p><pre data-lang="sql" class="programlisting">&gt; SET @@GLOBAL.group_replication_consistency= 'BEFORE';</pre><p>
          The possibility of setting the consistency level on specific
          sessions enables you to take advantage of scenarios such as:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              <span class="emphasis"><em>Scenario 6</em></span> A given system handles
              several instructions that do not require a strong
              consistency level, but one kind of instruction does
              require strong consistency: managing access permissions to
              documents;. In this scenario, the system changes access
              permissions and it wants to be sure that all clients see
              the correct permission. You only need to <code class="literal">SET
              @@SESSION.group_replication_consistency=
              ‘AFTER’</code>, on those instructions and leave the
              other instructions to run with <code class="literal">EVENTUAL</code>
              set at the global scope.
            </p></li><li class="listitem"><p>
              <span class="emphasis"><em>Scenario 7</em></span> On the same system as
              described in Scenario 6, every day an instruction needs to
              do some analytical processing, and as such it requires to
              always read the most up-to-date data. To achieve this, you
              only need to <code class="literal">SET
              @@SESSION.group_replication_consistency=
              ‘BEFORE’</code> on that specific instruction.
</p></li></ul>
</div>
<p>
          To summarize, you do not need to run all transactions with a
          specific consistency level, especially if only some
          transactions actually require it.
        </p><p>
          Note that all read-write transactions are totally ordered in
          Group Replication, so even when you set the consistency level
          to <code class="literal">AFTER</code> for the current session this
          transaction waits until its changes are applied on all
          members, which means waiting for this and all preceding
          transactions that could be in the secondaries' queues. In
          practice, the consistency level <code class="literal">AFTER</code> waits
          for everything until and including this transaction.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h5 class="title"><a name="group-replication-consistency-level-impacts"></a>Impacts of Consistency Levels</h5>

</div>

</div>

</div>
<a class="indexterm" name="idm46444259517824"></a><p>
          Another way to classify the consistency levels is in terms of
          impact on the group, that is, the repercussions that the
          consistency levels have on the other members.
        </p><p>
          The <code class="literal">BEFORE</code> consistency level, apart from
          being ordered on the transaction stream, only impacts on the
          local member. That is, it does not require coordination with
          the other members and does not have repercussions on their
          transactions. In other words, <code class="literal">BEFORE</code> only
          impacts the transactions on which it is used.
        </p><p>
          The <code class="literal">AFTER</code> and
          <code class="literal">BEFORE_AND_AFTER</code> consistency levels do have
          side-effects on concurrent transactions executed on other
          members. These consistency levels make the other members
          transactions wait if transactions with the
          <code class="literal">EVENTUAL</code> consistency level start while a
          transaction with <code class="literal">AFTER</code> or
          <code class="literal">BEFORE_AND_AFTER</code> is executing. The other
          members wait until the <code class="literal">AFTER</code> transaction is
          committed on that member, even if the other member's
          transactions have the <code class="literal">EVENTUAL</code> consistency
          level. In other words, <code class="literal">AFTER</code> and
          <code class="literal">BEFORE_AND_AFTER</code> impact
          <span class="emphasis"><em>all</em></span> <code class="literal">ONLINE</code> group
          members.
        </p><p>
          To illustrate this further, imagine a group with 3 members,
          M1, M2 and M3. On member M1 a client issues:
        </p><pre data-lang="sql" class="programlisting">&gt; SET @@SESSION.group_replication_consistency= AFTER;
&gt; BEGIN;
&gt; INSERT INTO t1 VALUES (1);
&gt; COMMIT;</pre><p>
          Then, while the above transaction is being applied, on member
          M2 a client issues:
        </p><pre data-lang="sql" class="programlisting">&gt; SET SESSION group_replication_consistency= EVENTUAL;</pre><p>
          In this situation, even though the second transaction's
          consistency level is <code class="literal">EVENTUAL</code>, because it
          starts executing while the first transaction is already in the
          commit phase on M2, the second transaction has to wait for the
          first transaction to finish the commit and only then can it
          execute.
        </p><p>
          You can only use the consistency levels
          <code class="literal">BEFORE</code>, <code class="literal">AFTER</code> and
          <code class="literal">BEFORE_AND_AFTER</code> on
          <code class="literal">ONLINE</code> members, attempting to use them on
          members in other states causes a session error.
        </p><p>
          Transactions whose consistency level is not
          <code class="literal">EVENTUAL</code> hold execution until a timeout,
          configured by <a class="link" href="server-administration.html#sysvar_wait_timeout"><code class="literal">wait_timeout</code></a>
          value is reached, which defaults to 8 hours. If the timeout is
          reached an <code class="literal">ER_GR_HOLD_WAIT_TIMEOUT</code> error is
          thrown.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h5 class="title"><a name="group-replication-consistency-level-impact-election"></a>Impact of Consistency on Primary Election</h5>

</div>

</div>

</div>
<a class="indexterm" name="idm46444259492672"></a><p>
          This section describes how a group's consistency level impacts
          on a single-primary group that has elected a new primary. Such
          a group automatically detects failures and adjusts the view of
          the members that are active, in other words the membership
          configuration. Furthermore, if a group is deployed in
          single-primary mode, whenever the group's membership changes
          there is a check performed to detect if there is still a
          primary member in the group. If there is none, a new one is
          selected from the list of secondary members. Typically, this
          is known as the secondary promotion.
        </p><p>
          

          Given the fact that the system detects failures and
          reconfigures itself automatically, the user may also expect
          that once the promotion takes place, the new primary is in the
          exact state, data-wise, as that of the old one. In other
          words, the user may expect that there is no backlog of
          replicated transactions to be applied on the new primary once
          he is able to read from and write to it. In practical terms,
          the user may expect that once his application fails-over to
          the new primary, there would be no chance, even if
          temporarily, to read old data or write into old data records.
        </p><p>
          When flow control is activated and properly tuned on a group,
          there is only a small chance of transiently reading stale data
          from a newly elected primary immediately after the promotion,
          as there should not be a backlog, or if there is one it should
          be small. Moreover, you might have a proxy or middleware
          layers that govern application accesses to the primary after a
          promotion and enforce the consistency criteria at that level.
          If your group members are using MySQL 8.0.14 or higher, you
          can specify the behavior of the new primary once it is
          promoted using the
          <a class="link" href="group-replication.html#sysvar_group_replication_consistency"><code class="literal">group_replication_consistency</code></a>
          variable, which controls whether a newly elected primary
          blocks both reads and writes until after the backlog is fully
          applied or if it behaves in the manner of members running
          MySQL 8.0.13 or earlier. If the
          <a class="link" href="group-replication.html#sysvar_group_replication_consistency"><code class="literal">group_replication_consistency</code></a>
          option was set to
          <code class="literal">BEFORE_ON_PRIMARY_FAILOVER</code> on a newly
          elected primary which has backlog to apply, and transactions
          are issued against the new primary while it is still applying
          the backlog, incoming transactions are blocked until the
          backlog is fully applied. Thus, the following anomalies are
          prevented:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              No stale reads for read-only and read-write transactions.
              This prevents stale reads from being externalized to the
              application by the new primary.
            </p></li><li class="listitem"><p>
              No spurious roll backs for read-write transactions, due to
              write-write conflicts with replicated read-write
              transactions still in the backlog waiting to be applied.
            </p></li><li class="listitem"><p>
              No read skew on read-write transactions, such as:
            </p><pre data-lang="sql" class="programlisting">        
&gt; BEGIN;
&gt; SELECT x FROM t1; -- x=1 because x=2 is in the backlog;
&gt; INSERT x INTO t2;
&gt; COMMIT;</pre><p>
              This query should not cause a conflict but writes outdated
              values.
</p></li></ul>
</div>
<p>
          To summarize, when
          <a class="link" href="group-replication.html#sysvar_group_replication_consistency"><code class="literal">group_replication_consistency</code></a>
          is set to <code class="literal">BEFORE_ON_PRIMARY_FAILOVER</code> you
          are choosing to prioritize consistency over availability,
          because reads and writes are held whenever a new primary is
          elected. This is the trade-off you have to consider when
          configuring your group. It should also be remembered that if
          flow control is working correctly, backlog should be minimal.
          Note that the higher consistency levels
          <code class="literal">BEFORE</code>, <code class="literal">AFTER</code>, and
          <code class="literal">BEFORE_AND_AFTER</code> also include the
          consistency guarantees provided by
          <code class="literal">BEFORE_ON_PRIMARY_FAILOVER</code>.
        </p><p>
          To guarantee that the group provides the same consistency
          level regardless of which member is promoted to primary, all
          members of the group should have
          <code class="literal">BEFORE_ON_PRIMARY_FAILOVER</code> (or a higher
          consistency level) persisted to their configuration. For
          example on each member issue:
        </p><pre data-lang="sql" class="programlisting">&gt; SET PERSIST group_replication_consistency='BEFORE_ON_PRIMARY_FAILOVER';</pre><p>
          This ensures that the members all behave in the same way, and
          that the configuration is persisted after a restart of the
          member.
        </p><p>
          Although all writes are held when using
          <code class="literal">BEFORE_ON_PRIMARY_FAILOVER</code> consistency
          level, not all reads are blocked to ensure that you can still
          inspect the server while it is applying backlog after a
          promotion took place. This is useful for debugging,
          monitoring, observability and troubleshooting. Some queries
          that do not modify data are allowed, such as the following:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              <a class="link" href="sql-statements.html#show" title="13.7.7 SHOW Statements"><code class="literal">SHOW</code></a> statements
            </p></li><li class="listitem"><p>
              <a class="link" href="data-types.html#set" title="11.3.6 The SET Type"><code class="literal">SET</code></a> statements
            </p></li><li class="listitem"><p>
              <a class="link" href="sql-statements.html#do" title="13.2.3 DO Statement"><code class="literal">DO</code></a> statements
            </p></li><li class="listitem"><p>
              <code class="literal">EMPTY</code> statements
            </p></li><li class="listitem"><p>
              <a class="link" href="sql-statements.html#use" title="13.8.4 USE Statement"><code class="literal">USE</code></a> statements
            </p></li><li class="listitem"><p>
              using <a class="link" href="sql-statements.html#select" title="13.2.10 SELECT Statement"><code class="literal">SELECT</code></a> statements
              against the <code class="literal">performance_schema</code> and
              <code class="literal">sys</code> databases
            </p></li><li class="listitem"><p>
              using <a class="link" href="sql-statements.html#select" title="13.2.10 SELECT Statement"><code class="literal">SELECT</code></a> statements
              against the <code class="literal">PROCESSLIST</code> table from the
              <code class="literal">infoschema</code> database
            </p></li><li class="listitem"><p>
              <a class="link" href="sql-statements.html#select" title="13.2.10 SELECT Statement"><code class="literal">SELECT</code></a> statements that do
              not use tables or user defined functions
            </p></li><li class="listitem"><p>
              <a class="link" href="sql-statements.html#stop-group-replication" title="13.4.3.2 STOP GROUP_REPLICATION Statement"><code class="literal">STOP GROUP_REPLICATION</code></a>
              statements
            </p></li><li class="listitem"><p>
              <a class="link" href="sql-statements.html#shutdown" title="13.7.8.9 SHUTDOWN Statement"><code class="literal">SHUTDOWN</code></a> statements
            </p></li><li class="listitem"><p>
              <a class="link" href="sql-statements.html#reset-persist" title="13.7.8.7 RESET PERSIST Statement"><code class="literal">RESET PERSIST</code></a> statements
</p></li></ul>
</div>
<p>
          A transaction cannot be on-hold forever, and if the time held
          exceeds <a class="link" href="server-administration.html#sysvar_wait_timeout"><code class="literal">wait_timeout</code></a> it
          returns an <span class="errortext">ER_GR_HOLD_WAIT_TIMEOUT</span>
          error.
</p>
</div>

</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="group-replication-distributed-recovery"></a>18.4.3 Distributed Recovery</h3>

</div>

</div>

</div>
<div class="toc">
<dl class="toc"><dt><span class="section"><a href="group-replication.html#group-replication-cloning">18.4.3.1 Cloning for Distributed Recovery</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-tuning-recovery">18.4.3.2 Configuring Distributed Recovery</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-distributed-recovery-fault">18.4.3.3 Fault Tolerance for Distributed Recovery</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-view-changes">18.4.3.4 How Distributed Recovery Works</a></span></dt></dl>
</div>
<a class="indexterm" name="idm46444259439520"></a><p>
      Whenever a member joins or rejoins a replication group, it must
      catch up with the transactions that were applied by the group
      members before it joined, or while it was away. This process is
      called distributed recovery.
    </p><p>
      The joining member begins by checking the relay log for its
      <code class="literal">group_replication_applier</code> channel for any
      transactions that it already received from the group but did not
      yet apply. If the joining member was in the group previously, it
      might find unapplied transactions from before it left, in which
      case it applies these as a first step. A member that is new to the
      group does not have anything to apply.
    </p><p>
      After this, the joining member connects to an online existing
      member to carry out state transfer. The joining member transfers
      all the transactions that took place in the group before it joined
      or while it was away, which are provided by the existing member
      (called the <span class="emphasis"><em>donor</em></span>). Next, the joining member
      applies the transactions that took place in the group while this
      state transfer was in progress. When this process is complete, the
      joining member has caught up with the remaining servers in the
      group, and it begins to participate normally in the group.
    </p><p>
      Group Replication uses a combination of these methods for state
      transfer during distributed recovery:

</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            A remote cloning operation using the clone plugin's
            function, which is available from MySQL 8.0.17. To enable
            this method of state transfer, you must install the clone
            plugin on the group members and the joining member. Group
            Replication automatically configures the required clone
            plugin settings and manages the remote cloning operation.
          </p></li><li class="listitem"><p>
            Replicating from a donor's binary log and applying the
            transactions on the joining member. This method uses a
            standard asynchronous replication channel named
            <code class="literal">group_replication_recovery</code> that is
            established between the donor and the joining member.
</p></li></ul>
</div>
<p>
    </p><p>
      Group Replication automatically selects the best combination of
      these methods for state transfer after you issue
      <a class="link" href="sql-statements.html#start-group-replication" title="13.4.3.1 START GROUP_REPLICATION Statement"><code class="literal">START GROUP_REPLICATION</code></a> on the
      joining member. To do this, Group Replication checks which
      existing members are suitable as donors, how many transactions the
      joining member needs from a donor, and whether any required
      transactions are no longer present in the binary log files on any
      group member. If the transaction gap between the joining member
      and a suitable donor is large, or if some required transactions
      are not in any donor's binary log files, Group Replication begins
      distributed recovery with a remote cloning operation. If there is
      not a large transaction gap, or if the clone plugin is not
      installed, Group Replication proceeds directly to state transfer
      from a donor's binary log.
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
          During a remote cloning operation, the existing data on the
          joining member is removed, and replaced with a copy of the
          donor's data. When the remote cloning operation is complete
          and the joining member has restarted, state transfer from a
          donor's binary log is carried out to get the transactions that
          the group applied while the remote cloning operation was in
          progress.
        </p></li><li class="listitem"><p>
          During state transfer from a donor's binary log, the joining
          member replicates and applies the required transactions from
          the donor's binary log, applying the transactions as they are
          received, up to the point where the binary log records that
          the joining member joined the group (a view change event).
          While this is in progress, the joining member buffers the new
          transactions that the group applies. When state transfer from
          the binary log is complete, the joining member applies the
          buffered transactions.
</p></li></ul>
</div>
<p>
      When the joining member is up to date with all the group's
      transactions, it is declared online and can participate in the
      group as a normal member, and distributed recovery is complete.
</p>
<div class="section">

<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="group-replication-cloning"></a>18.4.3.1 Cloning for Distributed Recovery</h4>
</div>
</div>
</div>
<p>
        MySQL Server's clone plugin is available from MySQL 8.0.17. If
        you want to use remote cloning operations for distributed
        recovery in a group, you must set up existing members and
        joining members beforehand to support this function. If you do
        not want to use this function in a group, do not set it up, in
        which case Group Replication only uses state transfer from the
        binary log.
      </p><p>
        To use cloning, at least one existing group member and the
        joining member must be set up beforehand to support remote
        cloning operations. As a minimum, you must install the clone
        plugin on the donor and joining member, grant the
        <a class="link" href="security.html#priv_backup-admin"><code class="literal">BACKUP_ADMIN</code></a> permission to the
        replication user for distributed recovery, and set the
        <a class="link" href="group-replication.html#sysvar_group_replication_clone_threshold"><code class="literal">group_replication_clone_threshold</code></a>
        system variable to an appropriate level. To ensure the maximum
        availability of donors, it is advisable to set up all current
        and future group members to support remote cloning operations.
      </p><p>
        Be aware that a remote cloning operation removes user-created
        tablespaces and data from the joining member before transferring
        the data from the donor. If the operation is stopped while in
        progress, the joining member might be left with partial data or
        no data. This can be repaired by retrying the remote cloning
        operation, which Group Replication does automatically.
</p>
<div class="section">

<div class="titlepage">
<div>
<div>
<h5 class="title"><a name="group-replication-cloning-prerequisites"></a>18.4.3.1.1 Prerequisites for Cloning</h5>
</div>
</div>
</div>
<p>
          For full instructions to set up and configure the clone
          plugin, see <a class="xref" href="server-administration.html#clone-plugin" title="5.6.7 The Clone Plugin">Section 5.6.7, “The Clone Plugin”</a> . Detailed
          prerequisites for a remote cloning operation are covered in
          <a class="xref" href="server-administration.html#clone-plugin-remote" title="5.6.7.3 Cloning Remote Data">Section 5.6.7.3, “Cloning Remote Data”</a> . For Group Replication,
          note the following key points and differences:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              The donor (an existing group member) and the recipient
              (the joining member) must have the clone plugin installed
              and active. For instructions to do this, see
              <a class="xref" href="server-administration.html#clone-plugin-installation" title="5.6.7.1 Installing the Clone Plugin">Section 5.6.7.1, “Installing the Clone Plugin”</a> .
            </p></li><li class="listitem"><p>
              The donor and the recipient must run on the same operating
              system, and must have the same MySQL Server version (which
              must be MySQL 8.0.17 or above to support the clone
              plugin). Cloning is therefore not suitable for groups
              where members run different MySQL Server versions.
            </p></li><li class="listitem"><p>
              The donor and the recipient must have the Group
              Replication plugin installed and active, and any other
              plugins that are active on the donor (such as a keyring
              plugin) must also be active on the recipient.
            </p></li><li class="listitem"><p>
              If distributed recovery is configured to use SSL
              (<a class="link" href="group-replication.html#sysvar_group_replication_recovery_use_ssl"><code class="literal">group_replication_recovery_use_ssl=ON</code></a>),
              Group Replication applies this setting for remote cloning
              operations. Group Replication automatically configures the
              settings for the clone SSL options
              (<a class="link" href="server-administration.html#sysvar_clone_ssl_ca"><code class="literal">clone_ssl_ca</code></a>,
              <a class="link" href="server-administration.html#sysvar_clone_ssl_cert"><code class="literal">clone_ssl_cert</code></a>, and
              <a class="link" href="server-administration.html#sysvar_clone_ssl_key"><code class="literal">clone_ssl_key</code></a>) to match
              your settings for the corresponding Group Replication
              distributed recovery options
              (<a class="link" href="group-replication.html#sysvar_group_replication_recovery_ssl_ca"><code class="literal">group_replication_recovery_ssl_ca</code></a>,
              <a class="link" href="group-replication.html#sysvar_group_replication_recovery_ssl_cert"><code class="literal">group_replication_recovery_ssl_cert</code></a>,
              and
              <a class="link" href="group-replication.html#sysvar_group_replication_recovery_ssl_key"><code class="literal">group_replication_recovery_ssl_key</code></a>).
            </p></li><li class="listitem"><p>
              You do not need to set up a list of valid donors in the
              <a class="link" href="server-administration.html#sysvar_clone_valid_donor_list"><code class="literal">clone_valid_donor_list</code></a>
              system variable for the purpose of joining a replication
              group. Group Replication configures this setting
              automatically for you after it selects a donor from the
              existing group members. Note that remote cloning
              operations use the server's SQL protocol hostname and
              port.
            </p></li><li class="listitem"><p>
              The clone plugin has a number of system variables to
              manage the network load and performance impact of the
              remote cloning operation. Group Replication does not
              configure these settings, so you can review them and set
              them if you want to, or allow them to default. Note that
              when a remote cloning operation is used for distributed
              recovery, the clone plugin's
              <a class="link" href="server-administration.html#sysvar_clone_enable_compression"><code class="literal">clone_enable_compression</code></a>
              setting applies to the operation, rather than the Group
              Replication compression setting.
            </p></li><li class="listitem"><p>
              To invoke the remote cloning operation on the recipient,
              Group Replication uses the internal
              <code class="literal">mysql.session</code> user, which already has
              the <a class="link" href="security.html#priv_clone-admin"><code class="literal">CLONE_ADMIN</code></a> privilege,
              so you do not need to set this up.
            </p></li><li class="listitem"><p>
              As the clone user on the donor for the remote cloning
              operation, Group Replication uses the replication user
              that you set up for distributed recovery (which is covered
              in <a class="xref" href="group-replication.html#group-replication-user-credentials" title="18.2.1.3 User Credentials">Section 18.2.1.3, “User Credentials”</a>).
              You must therefore give the
              <a class="link" href="security.html#priv_backup-admin"><code class="literal">BACKUP_ADMIN</code></a> privilege to
              this replication user on all group members that support
              cloning. Also give the privilege to the replication user
              on joining members when you are configuring them for Group
              Replication, because they can act as donors after they
              join the group. To give this privilege to the replication
              user on existing members, you can issue this statement on
              each group member individually with binary logging
              disabled, or on one group member with binary logging
              enabled:
            </p><pre data-lang="sql" class="programlisting">GRANT BACKUP_ADMIN ON *.* TO <em class="replaceable"><code>rpl_user</code></em>@'%';
</pre></li></ul>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h5 class="title"><a name="group-replication-cloning-threshold"></a>18.4.3.1.2 Threshold for Cloning</h5>

</div>

</div>

</div>
<p>
          When group members have been set up to support cloning, the
          <a class="link" href="group-replication.html#sysvar_group_replication_clone_threshold"><code class="literal">group_replication_clone_threshold</code></a>
          system variable specifies a threshold, expressed as a number
          of transactions, for the use of a remote cloning operation in
          distributed recovery. If the gap between the transactions on
          the donor and the transactions on the joining member is larger
          than this number, a remote cloning operation is used for state
          transfer to the joining member when this is technically
          possible. Group Replication calculates whether the threshold
          has been exceeded based on the
          <a class="link" href="replication.html#sysvar_gtid_executed"><code class="literal">gtid_executed</code></a> sets of the
          existing group members. Using a remote cloning operation in
          the event of a large transaction gap lets you add new members
          to the group without transferring the group's data to the
          server manually beforehand, and also enables a member that is
          very out of date to catch up more efficiently.
        </p><p>
          The default setting for the
          <a class="link" href="group-replication.html#sysvar_group_replication_clone_threshold"><code class="literal">group_replication_clone_threshold</code></a>
          Group Replication system variable is extremely high (the
          maximum permitted sequence number for a transaction in a
          GTID), so it effectively deactivates cloning wherever state
          transfer from the binary log is possible. To enable Group
          Replication to select a remote cloning operation for state
          transfer where this is more appropriate, set the system
          variable to specify a number of transactions as the
          transaction gap above which you want cloning to take place.
</p>
<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Warning
</div>
<p>
            Do not use a low setting for
            <a class="link" href="group-replication.html#sysvar_group_replication_clone_threshold"><code class="literal">group_replication_clone_threshold</code></a>
            in an active group. If a number of transactions above the
            threshold takes place in the group while the remote cloning
            operation is in progress, the joining member triggers a
            remote cloning operation again after restarting, and could
            continue this indefinitely. To avoid this situation, ensure
            that you set the threshold to a number higher than the
            number of transactions that you would expect to occur in the
            group during the time taken for the remote cloning
            operation.
</p>
</div>
<p>
          Group Replication attempts to execute a remote cloning
          operation regardless of your threshold when state transfer
          from a donor's binary log is impossible, for example because
          the transactions needed by the joining member are not
          available in the binary log on any existing group member.
          Group Replication identifies this based on the
          <a class="link" href="replication.html#sysvar_gtid_purged"><code class="literal">gtid_purged</code></a> sets of the
          existing group members. You cannot use the
          <a class="link" href="group-replication.html#sysvar_group_replication_clone_threshold"><code class="literal">group_replication_clone_threshold</code></a>
          system variable to deactivate cloning when the required
          transactions are not available in any member's binary log
          files, because in that situation cloning is the only
          alternative to transferring data to the joining member
          manually.
</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h5 class="title"><a name="group-replication-cloning-operations"></a>18.4.3.1.3 Cloning Operations</h5>

</div>

</div>

</div>
<p>
          When group members and joining members are set up for cloning,
          Group Replication manages remote cloning operations for you. A
          remote cloning operation might take some time to complete,
          depending on the size of the data. See
          <a class="xref" href="server-administration.html#clone-plugin-monitoring" title="5.6.7.9 Monitoring Cloning Operations">Section 5.6.7.9, “Monitoring Cloning Operations”</a> for information on
          monitoring the process.
</p>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Note
</div>
<p>
            When state transfer is complete, Group Replication restarts
            the joining member to complete the process. If
            <a class="link" href="group-replication.html#sysvar_group_replication_start_on_boot"><code class="literal">group_replication_start_on_boot=OFF</code></a>
            is set on the joining member, you must issue
            <a class="link" href="sql-statements.html#start-group-replication" title="13.4.3.1 START GROUP_REPLICATION Statement"><code class="literal">START GROUP_REPLICATION</code></a>
            manually again following this restart. If
            <a class="link" href="group-replication.html#sysvar_group_replication_start_on_boot"><code class="literal">group_replication_start_on_boot=ON</code></a>
            and other settings required to start Group Replication were
            set in a configuration file or using a <code class="literal">SET
            PERSIST</code> statement, you do not need to intervene
            and the process continues automatically to bring the joining
            member online.
</p>
</div>
<p>
          A remote cloning operation clones settings that are persisted
          in tables from the donor to the recipient, as well as the
          data. Group Replication manages the settings that relate
          specifically to Group Replication channels. Group Replication
          member settings that are persisted in configuration files,
          such as the group replication local address, are not cloned
          and are not changed on the joining member.
        </p><p>
          The credentials used by the donor for the
          <code class="literal">group_replication_recovery</code> replication
          channel (the replication user and password) are transferred to
          and used by the joining member after cloning, and they must be
          valid there. All group members that received state transfer by
          a remote cloning operation therefore use the same replication
          user and password for distributed recovery. However, Group
          Replication preserves the channel settings that relate to the
          use of SSL, so these are unique to the individual member.
        </p><p>
          If a <code class="literal">PRIVILEGE_CHECKS_USER</code> account has been
          used to help secure the replication appliers (see
          <a class="xref" href="replication.html#replication-privilege-checks-gr" title="17.3.3.2 Privilege Checks For Group Replication Channels">Section 17.3.3.2, “Privilege Checks For Group Replication Channels”</a>), from MySQL
          8.0.19, the <code class="literal">PRIVILEGE_CHECKS_USER</code> account
          and related settings from the donor are cloned to the joining
          member. If the joining member is set to start Group
          Replication on boot, it automatically uses the account for
          privilege checks on the appropriate replication channels. (In
          MySQL 8.0.18, due to a number of limitations, it is
          recommended that you do not use a
          <code class="literal">PRIVILEGE_CHECKS_USER</code> account with Group
          Replication channels.)
</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h5 class="title"><a name="group-replication-cloning-manual"></a>18.4.3.1.4 Cloning for Other Purposes</h5>

</div>

</div>

</div>
<p>
          Group Replication initiates and manages cloning operations for
          distributed recovery. Group members that have been set up to
          support cloning may also participate in cloning operations
          that a user initiates manually. For example, you might want to
          create a new server instance by cloning from a group member as
          the donor, but you do not want the new server instance to join
          the group immediately, or maybe not ever.
        </p><p>
          In all releases that support cloning, you can initiate a
          cloning operation manually involving a group member on which
          Group Replication is stopped. Note that because cloning
          requires that the active plugins on a donor and recipient must
          match, the Group Replication plugin must be installed and
          active on the other server instance, even if you do not intend
          that server instance to join a group. You can install the
          plugin by issuing this statement:
        </p><pre data-lang="sql" class="programlisting">INSTALL PLUGIN group_replication SONAME 'group_replication.so';</pre><p>
          In releases before MySQL 8.0.20, you cannot initiate a cloning
          operation manually if the operation involves a group member on
          which Group Replication is running. From MySQL 8.0.20, you can
          do this, provided that the cloning operation does not remove
          and replace the data on the recipient. The statement to
          initiate the cloning operation must therefore include the
          <code class="literal">DATA DIRECTORY</code> clause if Group Replication
          is running.
</p>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="group-replication-tuning-recovery"></a>18.4.3.2 Configuring Distributed Recovery</h4>

</div>

</div>

</div>
<a class="indexterm" name="idm46444259350544"></a><p>
        Several aspects of Group Replication's distributed recovery
        process can be configured to suit your system.
</p>
<div class="simplesect">

<div class="titlepage">
<div>

<div class="simple">
<h5 class="title"><a name="idm46444259348512"></a>Replication User for Distributed Recovery</h5>
</div>
</div>
</div>
<p>
          Distributed recovery requires a replication user that has the
          correct permissions so that Group Replication can establish
          direct member-to-member replication channels. The replication
          user must also have the correct permissions to act as the
          clone user on the donor for a remote cloning operation. For
          instructions to set up this replication user, see
          <a class="xref" href="group-replication.html#group-replication-user-credentials" title="18.2.1.3 User Credentials">Section 18.2.1.3, “User Credentials”</a>.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h5 class="title"><a name="idm46444259346112"></a>Manual State Transfer</h5>

</div>

</div>

</div>
<p>
          State transfer from the binary log is Group Replication's base
          mechanism for distributed recovery, and if the donors and
          joining members in your replication group are not set up to
          support cloning, this is the only available option. As state
          transfer from the binary log is based on classic asynchronous
          replication, it might take a very long time if the server
          joining the group does not have the group's data at all, or
          has data taken from a very old backup image. In this
          situation, it is therefore recommended that before adding a
          server to the group, you should set it up with the group's
          data by transferring a fairly recent snapshot of a server
          already in the group. This minimizes the time taken for
          distributed recovery, and reduces the impact on donor servers,
          since they have to retain and transfer fewer binary log files.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h5 class="title"><a name="idm46444259343936"></a>Number of Connection Attempts</h5>

</div>

</div>

</div>
<p>
          For state transfer from the binary log, Group Replication
          limits the number of attempts a joining member makes when
          trying to connect to a donor from the pool of donors. If the
          connection retry limit is reached without a successful
          connection, the distributed recovery procedure terminates with
          an error. Note that this limit specifies the total number of
          attempts that the joining member makes to connect to a donor.
          For example, if 2 group members are suitable donors, and the
          connection retry limit is set to 4, the joining member makes 2
          attempts to connect to each of the donors before reaching the
          limit.
        </p><p>
          The default connection retry limit is 10. You can configure
          this setting using the
          <a class="link" href="group-replication.html#sysvar_group_replication_recovery_retry_count"><code class="literal">group_replication_recovery_retry_count</code></a>
          system variable. The following command sets the maximum number
          of attempts to connect to a donor to 5:
        </p><pre data-lang="sql" class="programlisting">mysql&gt; <strong class="userinput"><code>SET GLOBAL group_replication_recovery_retry_count= 5;</code></strong>
</pre><p>
          For remote cloning operations, this limit does not apply.
          Group Replication makes only one connection attempt to each
          suitable donor for cloning, before starting to attempt state
          transfer from the binary log.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h5 class="title"><a name="idm46444259337792"></a>Sleep Interval for Connection Attempts</h5>

</div>

</div>

</div>
<p>
          For state transfer from the binary log, the
          <a class="link" href="group-replication.html#sysvar_group_replication_recovery_reconnect_interval"><code class="literal">group_replication_recovery_reconnect_interval</code></a>
          system variable defines how much time the distributed recovery
          process should sleep between donor connection attempts. Note
          that distributed recovery does not sleep after every donor
          connection attempt. As the joining member is connecting to
          different servers and not to the same one repeatedly, it can
          assume that the problem that affects server A does not affect
          server B. Distributed recovery therefore suspends only when it
          has gone through all the possible donors. Once the server
          joining the group has made one attempt to connect to each of
          the suitable donors in the group, the distributed recovery
          process sleeps for the number of seconds configured by the
          <a class="link" href="group-replication.html#sysvar_group_replication_recovery_reconnect_interval"><code class="literal">group_replication_recovery_reconnect_interval</code></a>
          system variable. For example, if 2 group members are suitable
          donors, and the connection retry limit is set to 4, the
          joining member makes one attempt to connect to each of the
          donors, then sleeps for the connection retry interval, then
          makes one further attempt to connect to each of the donors
          before reaching the limit.
        </p><p>
          The default connection retry interval is 60 seconds, and you
          can change this value dynamically. The following command sets
          the distributed recovery donor connection retry interval to
          120 seconds:
        </p><pre data-lang="sql" class="programlisting">mysql&gt; <strong class="userinput"><code>SET GLOBAL group_replication_recovery_reconnect_interval= 120;</code></strong>
</pre><p>
          For remote cloning operations, this interval does not apply.
          Group Replication makes only one connection attempt to each
          suitable donor for cloning, before starting to attempt state
          transfer from the binary log.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h5 class="title"><a name="idm46444259328960"></a>Marking the Joining Member Online</h5>

</div>

</div>

</div>
<p>
          When distributed recovery has successfully completed state
          transfer from the donor to the joining member, the joining
          member can be marked as online in the group and ready to
          participate. By default, this is done after the joining member
          has received and applied all the transactions that it was
          missing. Optionally, you can allow a joining member to be
          marked as online when it has received and certified (that is,
          completed conflict detection for) all the transactions that it
          was missing, but before it has applied them. If you want to do
          this, use the
          <a class="link" href="group-replication.html#sysvar_group_replication_recovery_complete_at"><code class="literal">group_replication_recovery_complete_at</code></a>
          system variable to specify the alternative setting
          <code class="literal">TRANSACTIONS_CERTIFIED</code>.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h5 class="title"><a name="idm46444259324912"></a>SSL and Authentication for Distributed Recovery</h5>

</div>

</div>

</div>
<p>
          You can optionally use SSL for distributed recovery
          connections between group members. SSL for distributed
          recovery is configured separately from SSL for normal group
          communications, which is determined by the server's SSL
          settings and the
          <a class="link" href="group-replication.html#sysvar_group_replication_ssl_mode"><code class="literal">group_replication_ssl_mode</code></a>
          system variable. For distributed recovery connections,
          dedicated Group Replication distributed recovery SSL system
          variables are available to configure the use of certificates
          and ciphers specifically for distributed recovery.
        </p><p>
          By default, SSL is not used for distributed recovery
          connections. To activate this, set
          <a class="link" href="group-replication.html#sysvar_group_replication_recovery_use_ssl"><code class="literal">group_replication_recovery_use_ssl=ON</code></a>,
          and configure the Group Replication distributed recovery SSL
          system variables as described in
          <a class="xref" href="group-replication.html#group-replication-secure-socket-layer-support-ssl" title="18.5.2 Group Replication Secure Socket Layer (SSL) Support">Section 18.5.2, “Group Replication Secure Socket Layer (SSL) Support”</a>.
          You need a replication user that is set up to use SSL.
        </p><p>
          When distributed recovery is configured to use SSL, Group
          Replication applies this setting for remote cloning
          operations, as well as for state transfer from a donor's
          binary log. Group Replication automatically configures the
          settings for the clone SSL options
          (<a class="link" href="server-administration.html#sysvar_clone_ssl_ca"><code class="literal">clone_ssl_ca</code></a>,
          <a class="link" href="server-administration.html#sysvar_clone_ssl_cert"><code class="literal">clone_ssl_cert</code></a>, and
          <a class="link" href="server-administration.html#sysvar_clone_ssl_key"><code class="literal">clone_ssl_key</code></a>) to match your
          settings for the corresponding Group Replication distributed
          recovery options
          (<a class="link" href="group-replication.html#sysvar_group_replication_recovery_ssl_ca"><code class="literal">group_replication_recovery_ssl_ca</code></a>,
          <a class="link" href="group-replication.html#sysvar_group_replication_recovery_ssl_cert"><code class="literal">group_replication_recovery_ssl_cert</code></a>,
          and
          <a class="link" href="group-replication.html#sysvar_group_replication_recovery_ssl_key"><code class="literal">group_replication_recovery_ssl_key</code></a>).
        </p><p>
          If you are not using SSL for distributed recovery (so
          <a class="link" href="group-replication.html#sysvar_group_replication_recovery_use_ssl"><code class="literal">group_replication_recovery_use_ssl</code></a>
          is set to <code class="literal">OFF</code>), and the replication user
          account for Group Replication authenticates with the
          <code class="literal">caching_sha2_password</code> plugin (which is the
          default in MySQL 8.0) or the
          <code class="literal">sha256_password</code> plugin, RSA key-pairs are
          used for password exchange. In this case, either use the
          <a class="link" href="group-replication.html#sysvar_group_replication_recovery_public_key_path"><code class="literal">group_replication_recovery_public_key_path</code></a>
          system variable to specify the RSA public key file, or use the
          <a class="link" href="group-replication.html#sysvar_group_replication_recovery_get_public_key"><code class="literal">group_replication_recovery_get_public_key</code></a>
          system variable to request the public key from the master, as
          described in
          <a class="xref" href="group-replication.html#group-replication-caching-sha2-user-credentials" title="Using Group Replication and the Caching SHA-2 User Credentials Plugin">Using Group Replication and the Caching SHA-2 User Credentials Plugin</a>.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h5 class="title"><a name="group-replication-recovery-compression"></a>Compression for Distributed Recovery</h5>

</div>

</div>

</div>
<p>
          From MySQL 8.0.18, you can optionally configure compression
          for distributed recovery by the method of state transfer from
          a donor's binary log. Compression can benefit distributed
          recovery where network bandwidth is limited and the donor has
          to transfer many transactions to the joining member. The
          <a class="link" href="group-replication.html#sysvar_group_replication_recovery_compression_algorithm"><code class="literal">group_replication_recovery_compression_algorithm</code></a>
          and
          <a class="link" href="group-replication.html#sysvar_group_replication_recovery_zstd_compression_level"><code class="literal">group_replication_recovery_zstd_compression_level</code></a>
          system variables configure permitted compression algorithms,
          and the <code class="literal">zstd</code> compression level, used when
          carrying out state transfer from a donor's binary log. For
          more information, see
          <a class="xref" href="programs.html#connection-compression-control" title="4.2.6 Connection Compression Control">Section 4.2.6, “Connection Compression Control”</a>.
        </p><p>
          Note that these compression settings do not apply for remote
          cloning operations. When a remote cloning operation is used
          for distributed recovery, the clone plugin's
          <a class="link" href="server-administration.html#sysvar_clone_enable_compression"><code class="literal">clone_enable_compression</code></a>
          setting applies.
</p>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="group-replication-distributed-recovery-fault"></a>18.4.3.3 Fault Tolerance for Distributed Recovery</h4>

</div>

</div>

</div>
<p>
        Group Replication's distributed recovery process has a number of
        built-in measures to ensure fault tolerance in the event of any
        problems during the process.
      </p><p>
        The donor for distributed recovery is selected randomly from the
        existing list of suitable online group members in the current
        view. Selecting a random donor means that there is a good chance
        that the same server is not selected more than once when
        multiple members enter the group. From MySQL 8.0.17, for state
        transfer from the binary log, the joiner only selects a donor
        that is running a lower or equal patch version of MySQL Server
        compared to itself. For earlier releases, all of the online
        members are allowed to be a donor. For a remote cloning
        operation, the joiner only selects a donor that is running the
        same patch version as itself. Note that when the joining member
        has restarted at the end of the operation, it establishes a
        connection with a new donor for state transfer from the binary
        log, which might be a different member from the original donor
        used for the remote cloning operation.
      </p><p>
        In the following situations, Group Replication detects an error
        in distributed recovery, automatically switches over to a new
        donor, and retries the state transfer:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            <span class="emphasis"><em>Connection error</em></span> - There is an
            authentication issue or another problem with making the
            connection to a candidate donor.
          </p></li><li class="listitem"><p>
            <span class="emphasis"><em>Replication errors</em></span> - One of the
            replication threads (the receiver or applier threads) being
            used for state transfer from the binary log fails. Because
            this method of state transfer uses the existing MySQL
            replication framework, it is possible that some transient
            errors could cause errors in the receiver or applier
            threads.
          </p></li><li class="listitem"><p>
            <span class="emphasis"><em>Remote cloning operation errors</em></span> - A
            remote cloning operation fails or is stopped before it
            completes.
          </p></li><li class="listitem"><p>
            <span class="emphasis"><em>Donor leaves the group</em></span> - The donor
            leaves the group, or Group Replication is stopped on the
            donor, while state transfer is in progress.
</p></li></ul>
</div>
<p>
        The Performance Schema table
        <a class="link" href="performance-schema.html#replication-applier-status-by-worker-table" title="26.12.11.6 The replication_applier_status_by_worker Table"><code class="literal">replication_applier_status_by_worker</code></a>
        displays the error that caused the last retry. In these
        situations, the new connection following the error is attempted
        with a new candidate donor. Selecting a different donor in the
        event of an error means that there is a chance the new candidate
        donor does not have the same error. If the clone plugin is
        installed, Group Replication attempts a remote cloning operation
        with each of the suitable online clone-supporting donors first.
        If all those attempts fail, Group Replication attempts state
        transfer from the binary log with all the suitable donors in
        turn, if that is possible.
</p>
<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Warning
</div>
<p>
          For a remote cloning operation, user-created tablespaces and
          data on the recipient (the joining member) are dropped before
          the remote cloning operation begins to transfer the data from
          the donor. If the remote cloning operation starts but does not
          complete, the joining member might be left with a partial set
          of its original data files, or with no user data. Data
          transferred by the donor is removed from the recipient if the
          cloning operation is stopped before the data is fully cloned.
          This situation can be repaired by retrying the cloning
          operation, which Group Replication does automatically.
</p>
</div>
<p>
        In the following situations, the distributed recovery process
        cannot be completed, and the joining member leaves the group:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            <span class="emphasis"><em>Purged transactions</em></span> - Transactions that
            are required by the joining member are not present in any
            online group member's binary log files, and the data cannot
            be obtained by a remote cloning operation (because the clone
            plugin is not installed, or because cloning was attempted
            with all possible donors but failed). The joining member is
            therefore unable to catch up with the group.
          </p></li><li class="listitem"><p>
            <span class="emphasis"><em>Conflicting transactions</em></span> - The joining
            member already contains some transactions that are not
            present in the group. If a remote cloning operation was
            carried out, these transactions would be deleted and lost,
            because the data directory on the joining member is erased.
            If state transfer from a donor's binary log was carried out,
            these transactions could conflict with the group's
            transactions.
          </p></li><li class="listitem"><p>
            <span class="emphasis"><em>Connection retry limit reached</em></span> - The
            joining member has made all the connection attempts allowed
            by the connection retry limit. You can configure this using
            the
            <a class="link" href="group-replication.html#sysvar_group_replication_recovery_retry_count"><code class="literal">group_replication_recovery_retry_count</code></a>
            system variable (see
            <a class="xref" href="group-replication.html#group-replication-tuning-recovery" title="18.4.3.2 Configuring Distributed Recovery">Section 18.4.3.2, “Configuring Distributed Recovery”</a>).
          </p></li><li class="listitem"><p>
            <span class="emphasis"><em>No more donors</em></span> - The joining member has
            unsuccessfully attempted a remote cloning operation with
            each of the online clone-supporting donors in turn (if the
            clone plugin is installed), then has unsuccessfully
            attempted state transfer from the binary log with each of
            the suitable online donors in turn, if possible.
          </p></li><li class="listitem"><p>
            <span class="emphasis"><em>Joining member leaves the group</em></span> - The
            joining member leaves the group or Group Replication is
            stopped on the joining member while state transfer is in
            progress.
</p></li></ul>
</div>
<p>
        If the joining member left the group unintentionally, so in any
        situation listed above except the last, it proceeds to take the
        action specified by the
        <a class="link" href="group-replication.html#sysvar_group_replication_exit_state_action"><code class="literal">group_replication_exit_state_action</code></a>
        system variable.
</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="group-replication-view-changes"></a>18.4.3.4 How Distributed Recovery Works</h4>

</div>

</div>

</div>
<a class="indexterm" name="idm46444259266848"></a><a class="indexterm" name="idm46444259265360"></a><p>
        When Group Replication's distributed recovery process is
        carrying out state transfer from the binary log, to synchronize
        the joining member with the donor up to a specific point in
        time, the joining member and donor make use of GTIDs (see
        <a class="xref" href="replication.html#replication-gtids" title="17.1.3 Replication with Global Transaction Identifiers">Section 17.1.3, “Replication with Global Transaction Identifiers”</a>). However, GTIDs only
        provide a means to realize which transactions the joining member
        is missing. They do not help marking a specific point in time to
        which the server joining the group must catch up, nor do they
        convey certification information. This is the job of binary log
        view markers, which mark view changes in the binary log stream,
        and also contain additional metadata information, supplying the
        joining member with missing certification-related data.
      </p><p>
        This topic explains the role of view changes and the view change
        identifier, and the steps to carry out state transfer from the
        binary log.
</p>
<div class="simplesect">

<div class="titlepage">
<div>

<div class="simple">
<h5 class="title"><a name="group-replication-view-and-view-changes"></a>View and View Changes</h5>
</div>
</div>
</div>
<p>
          A <span class="emphasis"><em>view</em></span> corresponds to a group of members
          participating actively in the current configuration, in other
          words at a specific point in time. They are functioning
          correctly and online in the group.
        </p><p>
          A <span class="emphasis"><em>view change</em></span> occurs when a modification
          to the group configuration happens, such as a member joining
          or leaving. Any group membership change results in an
          independent view change communicated to all members at the
          same logical point in time.
        </p><p>
          A <span class="emphasis"><em>view identifier</em></span> uniquely identifies a
          view. It is generated whenever a view change happens.
        </p><p>
          At the group communication layer, view changes with their
          associated view identifiers mark boundaries between the data
          exchanged before and after a member joins. This concept is
          implemented through a binary log event: the"view change
          log event". The view identifier is recorded to demarcate
          transactions transmitted before and after changes happen in
          the group membership.
        </p><p>
          The view identifier itself is built from two parts: a randomly
          generated part, and a monotonically increasing integer. The
          randomly generated part is generated when the group is
          created, and remains unchanged while there is at least one
          member in the group. The integer is incremented every time a
          view change happens. Using these two different parts enables
          the view identifier to identify incremental group changes
          caused by members joining or leaving, and also to identify the
          situation where all members leave the group in a full group
          shutdown, so no information remains of what view the group was
          in. Randomly generating part of the identifier when the group
          is started from the beginning ensures that the data markers in
          the binary log remain unique, and an identical identifier is
          not reused after a full group shutdown, as this would cause
          issues with distributed recovery in the future.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h5 class="title"><a name="group-replication-begin-stable-group"></a>Begin: Stable Group</h5>

</div>

</div>

</div>
<p>
          All servers are online and processing incoming transactions
          from the group. Some servers may be a little behind in terms
          of transactions replicated, but eventually they converge. The
          group acts as one distributed and replicated database.
</p>
<div class="figure">
<a name="idm46444259252864"></a><p class="title"><b>Figure 18.8 Stable Group</b></p>
<div class="figure-contents">

<div class="mediaobject">
<img src="images/gr-recovery-1.png" width="534" height="525" alt="Servers S1, S2, and S3 are members of the group. The most recent item in all of their binary logs is transaction T20.">
</div>

</div>

</div>
<br class="figure-break">
</div>

<div class="simplesect">

<div class="titlepage">
<div>

<div class="simple">
<h5 class="title"><a name="group-replication-view-change-member-joins"></a>View Change: a Member Joins</h5>

</div>

</div>

</div>
<p>
          Whenever a new member joins the group and therefore a view
          change is performed, every online server queues a view change
          log event for execution. This is queued because before the
          view change, several transactions can be queued on the server
          to be applied and as such, these belong to the old view.
          Queuing the view change event after them guarantees a correct
          marking of when this happened.
        </p><p>
          Meanwhile, the joining member selects a suitable donor the
          donor from the list of online servers as stated by the
          membership service through the view abstraction. A member
          joins on view 4 and the online members write a view change
          event to the binary log.
</p>
<div class="figure">
<a name="idm46444259243280"></a><p class="title"><b>Figure 18.9 A Member Joins</b></p>
<div class="figure-contents">

<div class="mediaobject">
<img src="images/gr-recovery-2.png" width="654" height="559" alt="Server S4 joins the group and looks for a donor. Servers S1, S2, and S3 each queue the view change entry VC4 for their binary logs. Meanwhile, server S1 is receiving new transaction T21.">
</div>

</div>

</div>
<br class="figure-break">
</div>

<div class="simplesect">

<div class="titlepage">
<div>

<div class="simple">
<h5 class="title"><a name="group-replication-state-transfer-catching-up"></a>State Transfer: Catching Up</h5>

</div>

</div>

</div>
<p>
          If group members and the joining member are set up with the
          clone plugin (see
          <a class="xref" href="group-replication.html#group-replication-cloning" title="18.4.3.1 Cloning for Distributed Recovery">Section 18.4.3.1, “Cloning for Distributed Recovery”</a>), and the
          difference in transactions between the joining member and the
          group exceeds the threshold set for a remote cloning operation
          (<a class="link" href="group-replication.html#sysvar_group_replication_clone_threshold"><code class="literal">group_replication_clone_threshold</code></a>),
          Group Replication begins distributed recovery with a remote
          cloning operation. A remote cloning operation is also carried
          out if required transactions are no longer present in any
          group member's binary log files. During a remote cloning
          operation, the existing data on the joining member is removed,
          and replaced with a copy of the donor's data. When the remote
          cloning operation is complete and the joining member has
          restarted, state transfer from a donor's binary log is carried
          out to get the transactions that the group applied while the
          remote cloning operation was in progress. If there is not a
          large transaction gap, or if the clone plugin is not
          installed, Group Replication proceeds directly to state
          transfer from a donor's binary log.
        </p><p>
          For state transfer from a donor's binary log, a connection is
          established between the joining member and the donor and state
          transfer begins. This interaction with the donor continues
          until the server joining the group's applier thread
          processes the view change log event that corresponds to the
          view change triggered when the server joining the group came
          into the group. In other words, the server joining the group
          replicates from the donor, until it gets to the marker with
          the view identifier which matches the view marker it is
          already in.
</p>
<div class="figure">
<a name="idm46444259229680"></a><p class="title"><b>Figure 18.10 State Transfer: Catching Up</b></p>
<div class="figure-contents">

<div class="mediaobject">
<img src="images/gr-recovery-3.png" width="603" height="525" alt="Server S4 has chosen server S2 as the donor. State transfer is executed from server S2 to server S4 until the view change entry VC4 is reached (view_id = VC4). Server S4 uses a temporary applier buffer for state transfer, and its binary log is currently empty.">
</div>

</div>

</div>
<br class="figure-break"><p>
          As view identifiers are transmitted to all members in the
          group at the same logical time, the server joining the group
          knows at which view identifier it should stop replicating.
          This avoids complex GTID set calculations because the view
          identifier clearly marks which data belongs to each group
          view.
        </p><p>
          While the server joining the group is replicating from the
          donor, it is also caching incoming transactions from the
          group. Eventually, it stops replicating from the donor and
          switches to applying those that are cached.
</p>
<div class="figure">
<a name="idm46444259221360"></a><p class="title"><b>Figure 18.11 Queued Transactions</b></p>
<div class="figure-contents">

<div class="mediaobject">
<img src="images/gr-recovery-4.png" width="644" height="525" alt="State transfer is complete. Server S4 has applied the transactions up to T20 and written them to its binary log. Server S4 has cached transaction T21, which arrived after the view change, in a temporary applier buffer while recovering.">
</div>

</div>

</div>
<br class="figure-break">
</div>

<div class="simplesect">

<div class="titlepage">
<div>

<div class="simple">
<h5 class="title"><a name="group-replication-finish-caught-up"></a>Finish: Caught Up</h5>

</div>

</div>

</div>
<p>
          When the server joining the group recognizes a view change log
          event with the expected view identifier, the connection to the
          donor is terminated and it starts applying the cached
          transactions. Although it acts as a marker in the binary log,
          delimiting view changes, the view change log event also plays
          another role. It conveys the certification information as
          perceived by all servers when the server joining the group
          entered the group, in other words the last view change.
          Without it, the server joining the group would not have the
          necessary information to be able to certify (detect conflicts)
          subsequent transactions.
        </p><p>
          The duration of the catch up is not deterministic, because it
          depends on the workload and the rate of incoming transactions
          to the group. This process is completely online and the server
          joining the group does not block any other server in the group
          while it is catching up. Therefore the number of transactions
          the server joining the group is behind when it moves to this
          stage can, for this reason, vary and thus increase or decrease
          according to the workload.
        </p><p>
          When the server joining the group reaches zero queued
          transactions and its stored data is equal to the other
          members, its public state changes to online.
</p>
<div class="figure">
<a name="idm46444259209856"></a><p class="title"><b>Figure 18.12 Instance Online</b></p>
<div class="figure-contents">

<div class="mediaobject">
<img src="images/gr-recovery-5.png" width="597" height="525" alt="Server S4 is now an online member of the group. It has applied cached transaction T21, so its binary log shows the same items as the binary logs of the other group members, and it no longer needs the temporary applier buffer. New incoming transaction T22 is now received and applied by all group members.">
</div>

</div>

</div>
<br class="figure-break">
</div>

</div>

</div>

<div class="section">

<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="group-replication-network-partitioning"></a>18.4.4 Network Partitioning</h3>

</div>

</div>

</div>
<a class="indexterm" name="idm46444259201440"></a><p>
      The group needs to achieve consensus whenever a change that needs
      to be replicated happens. This is the case for regular
      transactions but is also required for group membership changes and
      some internal messaging that keeps the group consistent. Consensus
      requires a majority of group members to agree on a given decision.
      When a majority of group members is lost, the group is unable to
      progress and blocks because it cannot secure majority or quorum.
    </p><p>
      Quorum may be lost when there are multiple involuntary failures,
      causing a majority of servers to be removed abruptly from the
      group. For example in a group of 5 servers, if 3 of them become
      silent at once, the majority is compromised and thus no quorum can
      be achieved. In fact, the remaining two are not able to tell if
      the other 3 servers have crashed or whether a network partition
      has isolated these 2 alone and therefore the group cannot be
      reconfigured automatically.
    </p><p>
      On the other hand, if servers exit the group voluntarily, they
      instruct the group that it should reconfigure itself. In practice,
      this means that a server that is leaving tells others that it is
      going away. This means that other members can reconfigure the
      group properly, the consistency of the membership is maintained
      and the majority is recalculated. For example, in the above
      scenario of 5 servers where 3 leave at once, if the 3 leaving
      servers warn the group that they are leaving, one by one, then the
      membership is able to adjust itself from 5 to 2, and at the same
      time, securing quorum while that happens.
</p>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Note
</div>
<p>
        Loss of quorum is by itself a side-effect of bad planning. Plan
        the group size for the number of expected failures (regardless
        whether they are consecutive, happen all at once or are
        sporadic).

        
</p>
</div>
<p>
      The following sections explain what to do if the system partitions
      in such a way that no quorum is automatically achieved by the
      servers in the group.
</p>
<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Tip
</div>
<p>
        A primary that has been excluded from a group after a majority
        loss followed by a reconfiguration can contain extra
        transactions that are not included in the new group. If this
        happens, the attempt to add back the excluded member from the
        group results in an error with the message <span class="errortext">This
        member has more executed transactions than those present in the
        group.</span>
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h4 class="title"><a name="group-replication-detecting-partitions"></a>Detecting Partitions</h4>

</div>

</div>

</div>
<p>
        The <a class="link" href="performance-schema.html#replication-group-members-table" title="26.12.11.9 The replication_group_members Table"><code class="literal">replication_group_members</code></a>
        performance schema table presents the status of each server in
        the current view from the perspective of this server. The
        majority of the time the system does not run into partitioning,
        and therefore the table shows information that is consistent
        across all servers in the group. In other words, the status of
        each server on this table is agreed by all in the current view.
        However, if there is network partitioning, and quorum is lost,
        then the table shows the status <code class="literal">UNREACHABLE</code>
        for those servers that it cannot contact. This information is
        exported by the local failure detector built into Group
        Replication.
</p>
<div class="figure">
<a name="idm46444259188912"></a><p class="title"><b>Figure 18.13 Losing Quorum</b></p>
<div class="figure-contents">

<div class="mediaobject">
<img src="images/gr-majority-lost.png" width="265" height="417" alt="Five server instances, S1, S2, S3, S4, and S5, are deployed as an interconnected group, which is a stable group. When three of the servers, S3, S4, and S5, fail, the majority is lost and the group can no longer proceed without intervention.">
</div>

</div>

</div>
<br class="figure-break"><p>
        To understand this type of network partition the following
        section describes a scenario where there are initially 5 servers
        working together correctly, and the changes that then happen to
        the group once only 2 servers are online. The scenario is
        depicted in the

        

        figure.
      </p><p>
        As such, lets assume that there is a group with these 5 servers
        in it:

        
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            Server s1 with member identifier
            <code class="literal">199b2df7-4aaf-11e6-bb16-28b2bd168d07</code>
          </p></li><li class="listitem"><p>
            Server s2 with member identifier
            <code class="literal">199bb88e-4aaf-11e6-babe-28b2bd168d07</code>
          </p></li><li class="listitem"><p>
            Server s3 with member identifier
            <code class="literal">1999b9fb-4aaf-11e6-bb54-28b2bd168d07</code>
          </p></li><li class="listitem"><p>
            Server s4 with member identifier
            <code class="literal">19ab72fc-4aaf-11e6-bb51-28b2bd168d07</code>
          </p></li><li class="listitem"><p>
            Server s5 with member identifier
            <code class="literal">19b33846-4aaf-11e6-ba81-28b2bd168d07</code>
</p></li></ul>
</div>
<p>
        Initially the group is running fine and the servers are happily
        communicating with each other. You can verify this by logging
        into s1 and looking at its
        <a class="link" href="performance-schema.html#replication-group-members-table" title="26.12.11.9 The replication_group_members Table"><code class="literal">replication_group_members</code></a>
        performance schema table. For example:
      </p><pre data-lang="sql" class="programlisting">mysql&gt; <strong class="userinput"><code>SELECT MEMBER_ID,MEMBER_STATE, MEMBER_ROLE FROM performance_schema.replication_group_members;</code></strong>
+--------------------------------------+--------------+-------------+
| MEMBER_ID                            | MEMBER_STATE |-MEMBER_ROLE |
+--------------------------------------+--------------+-------------+
| 1999b9fb-4aaf-11e6-bb54-28b2bd168d07 | ONLINE       | SECONDARY   |
| 199b2df7-4aaf-11e6-bb16-28b2bd168d07 | ONLINE       | PRIMARY     |
| 199bb88e-4aaf-11e6-babe-28b2bd168d07 | ONLINE       | SECONDARY   |
| 19ab72fc-4aaf-11e6-bb51-28b2bd168d07 | ONLINE       | SECONDARY   |
| 19b33846-4aaf-11e6-ba81-28b2bd168d07 | ONLINE       | SECONDARY   |
+--------------------------------------+--------------+-------------+
</pre><p>
        However, moments later there is a catastrophic failure and
        servers s3, s4 and s5 stop unexpectedly. A few seconds after
        this, looking again at the
        <a class="link" href="performance-schema.html#replication-group-members-table" title="26.12.11.9 The replication_group_members Table"><code class="literal">replication_group_members</code></a> table on
        s1 shows that it is still online, but several others members are
        not. In fact, as seen below they are marked as
        <code class="literal">UNREACHABLE</code>. Moreover, the system could not
        reconfigure itself to change the membership, because the
        majority has been lost.
      </p><pre data-lang="sql" class="programlisting">mysql&gt; <strong class="userinput"><code>SELECT MEMBER_ID,MEMBER_STATE FROM performance_schema.replication_group_members;</code></strong>
+--------------------------------------+--------------+
| MEMBER_ID                            | MEMBER_STATE |
+--------------------------------------+--------------+
| 1999b9fb-4aaf-11e6-bb54-28b2bd168d07 | UNREACHABLE  |
| 199b2df7-4aaf-11e6-bb16-28b2bd168d07 | ONLINE       |
| 199bb88e-4aaf-11e6-babe-28b2bd168d07 | ONLINE       |
| 19ab72fc-4aaf-11e6-bb51-28b2bd168d07 | UNREACHABLE  |
| 19b33846-4aaf-11e6-ba81-28b2bd168d07 | UNREACHABLE  |
+--------------------------------------+--------------+
</pre><p>
        The table shows that s1 is now in a group that has no means of
        progressing without external intervention, because a majority of
        the servers are unreachable. In this particular case, the group
        membership list needs to be reset to allow the system to
        proceed, which is explained in this section. Alternatively, you
        could also choose to stop Group Replication on s1 and s2 (or
        stop completely s1 and s2), figure out what happened with s3, s4
        and s5 and then restart Group Replication (or the servers).
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h4 class="title"><a name="group-replication-unblocking-a-partition"></a>Unblocking a Partition</h4>

</div>

</div>

</div>
<p>
        Group replication enables you to reset the group membership list
        by forcing a specific configuration. For instance in the case
        above, where s1 and s2 are the only servers online, you could
        choose to force a membership configuration consisting of only s1
        and s2. This requires checking some information about s1 and s2
        and then using the
        <a class="link" href="group-replication.html#sysvar_group_replication_force_members"><code class="literal">group_replication_force_members</code></a>
        variable.
</p>
<div class="figure">
<a name="idm46444259157952"></a><p class="title"><b>Figure 18.14 Forcing a New Membership</b></p>
<div class="figure-contents">

<div class="mediaobject">
<img src="images/gr-majority-lost-to-stable-group.png" width="266" height="414" alt="Three of the servers in a group, S3, S4, and S5, have failed, so the majority is lost and the group can no longer proceed without intervention. With the intervention described in the following text, S1 and S2 are able to form a stable group by themselves.">
</div>

</div>

</div>
<br class="figure-break"><p>
        Suppose that you are back in the situation where s1 and s2 are
        the only servers left in the group. Servers s3, s4 and s5 have
        left the group unexpectedly. To make servers s1 and s2 continue,
        you want to force a membership configuration that contains only
        s1 and s2.
</p>
<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Warning
</div>
<p>
          This procedure uses
          <a class="link" href="group-replication.html#sysvar_group_replication_force_members"><code class="literal">group_replication_force_members</code></a>
          and should be considered a last resort remedy. It
          <span class="emphasis"><em>must</em></span> be used with extreme care and only
          for overriding loss of quorum. If misused, it could create an
          artificial split-brain scenario or block the entire system
          altogether.
</p>
</div>
<p>
        Recall that the system is blocked and the current configuration
        is the following (as perceived by the local failure detector on
        s1):
      </p><pre data-lang="sql" class="programlisting">mysql&gt; <strong class="userinput"><code>SELECT MEMBER_ID,MEMBER_STATE FROM performance_schema.replication_group_members;</code></strong>
+--------------------------------------+--------------+
| MEMBER_ID                            | MEMBER_STATE |
+--------------------------------------+--------------+
| 1999b9fb-4aaf-11e6-bb54-28b2bd168d07 | UNREACHABLE  |
| 199b2df7-4aaf-11e6-bb16-28b2bd168d07 | ONLINE       |
| 199bb88e-4aaf-11e6-babe-28b2bd168d07 | ONLINE       |
| 19ab72fc-4aaf-11e6-bb51-28b2bd168d07 | UNREACHABLE  |
| 19b33846-4aaf-11e6-ba81-28b2bd168d07 | UNREACHABLE  |
+--------------------------------------+--------------+
</pre><p>
        The first thing to do is to check what is the local address
        (group communication identifier) for s1 and s2. Log in to s1 and
        s2 and get that information as follows.
      </p><pre data-lang="sql" class="programlisting">mysql&gt; <strong class="userinput"><code>SELECT @@group_replication_local_address;</code></strong>
</pre><p>
        Once you know the group communication addresses of s1
        (<code class="literal">127.0.0.1:10000</code>) and s2
        (<code class="literal">127.0.0.1:10001</code>), you can use that on one of
        the two servers to inject a new membership configuration, thus
        overriding the existing one that has lost quorum. To do that on
        s1:
      </p><pre data-lang="sql" class="programlisting">mysql&gt; <strong class="userinput"><code>SET GLOBAL group_replication_force_members="</code></strong>127.0.0.1:10000,127.0.0.1:10001";
</pre><p>
        This unblocks the group by forcing a different configuration.
        Check <a class="link" href="performance-schema.html#replication-group-members-table" title="26.12.11.9 The replication_group_members Table"><code class="literal">replication_group_members</code></a> on
        both s1 and s2 to verify the group membership after this change.
        First on s1.
      </p><pre data-lang="sql" class="programlisting">mysql&gt; <strong class="userinput"><code>SELECT MEMBER_ID,MEMBER_STATE FROM performance_schema.replication_group_members;</code></strong>
+--------------------------------------+--------------+
| MEMBER_ID                            | MEMBER_STATE |
+--------------------------------------+--------------+
| b5ffe505-4ab6-11e6-b04b-28b2bd168d07 | ONLINE       |
| b60907e7-4ab6-11e6-afb7-28b2bd168d07 | ONLINE       |
+--------------------------------------+--------------+
</pre><p>
        And then on s2.
      </p><pre data-lang="sql" class="programlisting">mysql&gt; <strong class="userinput"><code>SELECT * FROM performance_schema.replication_group_members;</code></strong>
+--------------------------------------+--------------+
| MEMBER_ID                            | MEMBER_STATE |
+--------------------------------------+--------------+
| b5ffe505-4ab6-11e6-b04b-28b2bd168d07 | ONLINE       |
| b60907e7-4ab6-11e6-afb7-28b2bd168d07 | ONLINE       |
+--------------------------------------+--------------+
</pre><p>
        When forcing a new membership configuration, make sure that any
        servers are going to be forced out of the group are indeed
        stopped. In the scenario depicted above, if s3, s4 and s5 are
        not really unreachable but instead are online, they may have
        formed their own functional partition (they are 3 out of 5,
        hence they have the majority). In that case, forcing a group
        membership list with s1 and s2 could create an artificial
        split-brain situation. Therefore it is important before forcing
        a new membership configuration to ensure that the servers to be
        excluded are indeed shutdown and if they are not, shut them down
        before proceeding.
      </p><p>
        After you have used the
        <a class="link" href="group-replication.html#sysvar_group_replication_force_members"><code class="literal">group_replication_force_members</code></a>
        system variable to successfully force a new group membership and
        unblock the group, ensure that you clear the system variable.
        <a class="link" href="group-replication.html#sysvar_group_replication_force_members"><code class="literal">group_replication_force_members</code></a>
        must be empty in order to issue a <a class="link" href="sql-statements.html#start-group-replication" title="13.4.3.1 START GROUP_REPLICATION Statement"><code class="literal">START
        GROUP_REPLICATION</code></a> statement.
</p>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="group-replication-ipv6"></a>18.4.5 Support For IPv6 And For Mixed IPv6 And IPv4 Groups</h3>

</div>

</div>

</div>
<a class="indexterm" name="idm46444259125968"></a><a class="indexterm" name="idm46444259124512"></a><p>
      From MySQL 8.0.14, Group Replication group members can use IPv6
      addresses as an alternative to IPv4 addresses for communications
      within the group. To use IPv6 addresses, the operating system on
      the server host and the MySQL Server instance must both be
      configured to support IPv6. For instructions to set up IPv6
      support for a server instance, see <a class="xref" href="server-administration.html#ipv6-support" title="5.1.13 IPv6 Support">Section 5.1.13, “IPv6 Support”</a>.
    </p><p>
      IPv6 addresses, or host names that resolve to them, can be
      specified as the network address that the member provides in the
      <a class="link" href="group-replication.html#sysvar_group_replication_local_address"><code class="literal">group_replication_local_address</code></a>
      option for connections from other members. When specified with a
      port number, an IPv6 address must be specified in square brackets,
      for example:
    </p><pre data-lang="simple" class="programlisting">group_replication_local_address= "[2001:db8:85a3:8d3:1319:8a2e:370:7348]:33061"</pre><p>
      The network address or host name specified in
      <a class="link" href="group-replication.html#sysvar_group_replication_local_address"><code class="literal">group_replication_local_address</code></a>
      is used by Group Replication as the unique identifier for a group
      member within the replication group. If a host name specified as
      the Group Replication local address for a server instance resolves
      to both an IPv4 and an IPv6 address, the IPv4 address is always
      used for Group Replication connections. The address or host name
      specified as the Group Replication local address is not the same
      as the MySQL server SQL protocol host and port, and is not
      specified in the <a class="link" href="server-administration.html#sysvar_bind_address"><code class="literal">bind_address</code></a>
      system variable for the server instance. For the purpose of IP
      address whitelisting for Group Replication (see
      <a class="xref" href="group-replication.html#group-replication-ip-address-whitelisting" title="18.5.1 Group Replication IP Address Whitelisting">Section 18.5.1, “Group Replication IP Address Whitelisting”</a>), the
      address that you specify for each group member in
      <a class="link" href="group-replication.html#sysvar_group_replication_local_address"><code class="literal">group_replication_local_address</code></a>
      must be added to the list for the
      <a class="link" href="group-replication.html#sysvar_group_replication_ip_whitelist"><code class="literal">group_replication_ip_whitelist</code></a>
      option on the other servers in the replication group.
    </p><p>
      A replication group can contain a combination of members that
      present an IPv6 address as their Group Replication local address,
      and members that present an IPv4 address. When a server joins such
      a mixed group, it must make the initial contact with the seed
      member using the protocol that the seed member advertises in the
      <a class="link" href="group-replication.html#sysvar_group_replication_group_seeds"><code class="literal">group_replication_group_seeds</code></a>
      option, whether that is IPv4 or IPv6. If any of the seed members
      for the group are listed in the
      <a class="link" href="group-replication.html#sysvar_group_replication_group_seeds"><code class="literal">group_replication_group_seeds</code></a>
      option with an IPv6 address when a joining member has an IPv4
      Group Replication local address, or the reverse, you must also set
      up and whitelist an alternative address for the joining member for
      the required protocol (or a host name that resolves to an address
      for that protocol). If a joining member does not have a
      whitelisted address for the appropriate protocol, its connection
      attempt is refused. The alternative address or host name only
      needs to be added to the
      <a class="link" href="group-replication.html#sysvar_group_replication_ip_whitelist"><code class="literal">group_replication_ip_whitelist</code></a>
      option on the other servers in the replication group, not to the
      <a class="link" href="group-replication.html#sysvar_group_replication_local_address"><code class="literal">group_replication_local_address</code></a>
      value for the joining member (which can only contain a single
      address).
    </p><p>
      For example, server A is a seed member for a group, and has the
      following configuration settings for Group Replication, so that it
      is advertising an IPv6 address in the
      <a class="link" href="group-replication.html#sysvar_group_replication_group_seeds"><code class="literal">group_replication_group_seeds</code></a>
      option:
    </p><pre data-lang="simple" class="programlisting">group_replication_bootstrap_group=on
group_replication_local_address= "[2001:db8:85a3:8d3:1319:8a2e:370:7348]:33061"
group_replication_group_seeds= "[2001:db8:85a3:8d3:1319:8a2e:370:7348]:33061"</pre><p>
      Server B is a joining member for the group, and has the following
      configuration settings for Group Replication, so that it has an
      IPv4 Group Replication local address:
    </p><pre data-lang="simple" class="programlisting">group_replication_bootstrap_group=off
group_replication_local_address= "203.0.113.21:33061"
group_replication_group_seeds= "[2001:db8:85a3:8d3:1319:8a2e:370:7348]:33061"</pre><p>
      Server B also has an alternative IPv6 address
      <code class="literal">2001:db8:8b0:40:3d9c:cc43:e006:19e8</code>. For Server
      B to join the group successfully, both its IPv4 Group Replication
      local address, and its alternative IPv6 address, must be listed in
      Server A's whitelist, as in the following example:
    </p><pre data-lang="simple" class="programlisting">group_replication_ip_whitelist=
"203.0.113.0/24,2001:db8:85a3:8d3:1319:8a2e:370:7348, 
2001:db8:8b0:40:3d9c:cc43:e006:19e8"</pre><p>
      As a best practice for Group Replication IP whitelisting, Server B
      (and all other group members) should have the same whitelist as
      Server A, unless security requirements demand otherwise.
    </p><p>
      If any or all members of a replication group are using an older
      MySQL Server version that does not support the use of IPv6
      addresses for Group Replication, a member cannot participate in
      the group using an IPv6 address (or a host name that resolves to
      one) as its Group Replication local address. This applies both in
      the case where at least one existing member uses an IPv6 address
      and a new member that does not support this attempts to join, and
      in the case where a new member attempts to join using an IPv6
      address but the group includes at least one member that does not
      support this. In each situation, the new member cannot join. To
      make a joining member present an IPv4 address for group
      communications, you can either change the value of
      <a class="link" href="group-replication.html#sysvar_group_replication_local_address"><code class="literal">group_replication_local_address</code></a>
      to an IPv4 address, or configure your DNS to resolve the joining
      member's existing host name to an IPv4 address. After you have
      upgraded every group member to a MySQL Server version that
      supports IPv6 for Group Replication, you can change the
      <a class="link" href="group-replication.html#sysvar_group_replication_local_address"><code class="literal">group_replication_local_address</code></a>
      value for each member to an IPv6 address, or configure your DNS to
      present an IPv6 address. Changing the value of
      <a class="link" href="group-replication.html#sysvar_group_replication_local_address"><code class="literal">group_replication_local_address</code></a>
      takes effect only when you stop and restart Group Replication.
</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="group-replication-enterprise-backup"></a>18.4.6 Using MySQL Enterprise Backup with Group Replication</h3>

</div>

</div>

</div>
<a class="indexterm" name="idm46444259090288"></a><a class="indexterm" name="idm46444259088800"></a><p>
      <a class="ulink" href="https://dev.mysql.com/doc/mysql-enterprise-backup/8.0/en/" target="_top">MySQL Enterprise
      Backup</a> is a commercially-licensed backup utility for MySQL
      Server, available with
      <a class="ulink" href="https://www.mysql.com/products/enterprise/" target="_top">MySQL
      Enterprise Edition</a>. This section explains how to back up
      and subsequently restore a Group Replication member using MySQL Enterprise Backup.
      The same technique can be used to quickly add a new member to a
      group.
</p>
<h4><a name="idm46444259085152"></a>Backing up a Group Replication Member Using MySQL Enterprise Backup</h4>
<p>
      Backing up a Group Replication member is similar to backing up a
      stand-alone MySQL instance. The following instructions assume that
      you are already familiar with how to use MySQL Enterprise Backup to perform a
      backup; if that is not the case, please review the
      <a class="ulink" href="https://dev.mysql.com/doc/mysql-enterprise-backup/8.0/en/" target="_top">MySQL
      Enterprise Backup 8.0 User's Guide</a>, especially
      <a class="ulink" href="https://dev.mysql.com/doc/mysql-enterprise-backup/8.0/en/backing-up.html" target="_top">Backing Up a Database Server</a>. Also note the requirements described
      in <a class="ulink" href="https://dev.mysql.com/doc/mysql-enterprise-backup/8.0/en/mysqlbackup.privileges.html" target="_top">Grant MySQL Privileges to Backup Administrator</a> and
      <a class="ulink" href="https://dev.mysql.com/doc/mysql-enterprise-backup/8.0/en/meb-group-replication.html" target="_top">Using MySQL Enterprise Backup with Group Replication</a>.
    </p><p>
      Consider the following group with three members,
      <code class="literal">s1</code>, <code class="literal">s2</code>, and
      <code class="literal">s3</code>, running on hosts with the same names:
    </p><pre data-lang="sql" class="programlisting">mysql&gt; <strong class="userinput"><code>SELECT member_host, member_port, member_state FROM performance_schema.replication_group_members;</code></strong>
+-------------+-------------+--------------+
| member_host | member_port | member_state |
+-------------+-------------+--------------+
| s1          |        3306 | ONLINE       |
| s2          |        3306 | ONLINE       |
| s3          |        3306 | ONLINE       |
+-------------+-------------+--------------+
</pre><p>
      Using MySQL Enterprise Backup, create a backup of <code class="literal">s2</code> by issuing
      on its host, for example, the following command:
    </p><pre data-lang="terminal" class="programlisting">s2&gt; <strong class="userinput"><code>mysqlbackup --defaults-file=/etc/my.cnf --backup-image=/backups/my.mbi_`date +%d%m_%H%M` \ 
		      --backup-dir=/backups/backup_`date +%d%m_%H%M` --user=root -p \
--host=127.0.0.1 backup-to-image</code></strong></pre>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Notes
</div>

<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            If the system variable
            <a class="link" href="server-administration.html#sysvar_sql_require_primary_key"><code class="literal">sql_require_primary_key</code></a> is
            set to <code class="literal">ON</code> for the group, MySQL Enterprise Backup will not
            be able to log the backup progress on the servers. This is
            because the <code class="literal">backup_progress</code> table on the
            server is a CSV table, for which primary keys are not
            supported. In that case, <span class="command"><strong>mysqlbackup</strong></span>
            issues the following warnings during the backup operation:
          </p><pre class="programlisting">181011 11:17:06 MAIN WARNING: MySQL query 'CREATE TABLE IF NOT EXISTS
mysql.backup_progress( `backup_id` BIGINT NOT NULL, `tool_name` VARCHAR(4096)
NOT NULL, `error_code` INT NOT NULL, `error_message` VARCHAR(4096) NOT NULL,
`current_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP               ON
UPDATE CURRENT_TIMESTAMP,`current_state` VARCHAR(200) NOT NULL ) ENGINE=CSV
DEFAULT CHARSET=utf8 COLLATE=utf8_bin': 3750, Unable to create a table
without PK, when system variable 'sql_require_primary_key' is set. Add a PK
to the table or unset this variable to avoid this message. Note that tables
without PK can cause performance problems in row-based replication, so please
consult your DBA before changing this setting.
181011 11:17:06 MAIN WARNING: This backup operation's progress info cannot be
logged.</pre><p>
            This does not prevent <span class="command"><strong>mysqlbackup</strong></span> from
            finishing the backup though.
          </p></li><li class="listitem"><p>
            <span class="emphasis"><em>For MySQL Enterprise Backup 8.0.11</em></span>, when backing up a
            secondary member, as MySQL Enterprise Backup cannot write backup status and
            metadata to a read-only server instance, it issues the
            following warnings during the backup operation:
          </p><pre class="programlisting">181113 21:31:08 MAIN WARNING: This backup operation cannot write to backup
progress. The MySQL server is running with the --super-read-only option.</pre><p>
            You can avoid the warning by using the
            <code class="option">--no-history-logging</code> option with your
            backup command. This is not an issue for MySQL Enterprise Backup 8.0.12 and
            higher—see <a class="ulink" href="https://dev.mysql.com/doc/mysql-enterprise-backup/8.0/en/meb-group-replication.html" target="_top">Using MySQL Enterprise Backup with Group Replication</a> for
            details.
</p></li></ul>
</div>

</div>
<h4><a name="group-replication-restore-failed-member"></a>Restoring a Failed Member</h4>
<p>
      Assume one of the members (<code class="literal">s3</code> in the following
      example) is irreconcilably corrupted. The most recent backup of
      group member <code class="literal">s2</code> can be used to restore
      <code class="literal">s3</code>. Here are the steps for performing the
      restore:
</p>
<div class="orderedlist">
<ol class="orderedlist" type="1"><li class="listitem"><p>
          <span class="emphasis"><em>Copy the backup of s2 onto the host for
          s3.</em></span> The exact way to copy the backup depends on the
          operating system and tools available to you. In this example,
          we assume the hosts are both Linux servers and use SCP to copy
          the files between them:
        </p><pre data-lang="terminal" class="programlisting">s2/backups&gt; <strong class="userinput"><code>scp my.mbi_2206_1429 s3:/backups</code></strong></pre></li><li class="listitem"><p>
          <span class="emphasis"><em>Restore the backup.</em></span> Connect to the target
          host (the host for <code class="literal">s3</code> in this case), and
          restore the backup using MySQL Enterprise Backup. Here are the steps:
</p>
<div class="orderedlist">
<ol class="orderedlist" type="a"><li class="listitem"><p>
              Stop the corrupted server, if it is still running. For
              example, on Linux distributions that use systemd:
            </p><pre class="programlisting">s3&gt; systemctl stop mysqld</pre></li><li class="listitem"><p>
              Preserve the two configuration files in the corrupted
              server's data directory, <code class="filename">auto.cnf</code> and
              <code class="filename">mysqld-auto.cnf</code> (if it exists), by
              copying them to a safe location outside of the data
              directory. This is for preserving the
              <a class="link" href="replication.html#sysvar_server_uuid">server's UUID</a>
              and <a class="xref" href="server-administration.html#persisted-system-variables" title="5.1.9.3 Persisted System Variables">Section 5.1.9.3, “Persisted System Variables”</a> (if
              used), which are needed in the steps below.
            </p></li><li class="listitem"><p>
              Delete all contents in the data directory of
              <code class="literal">s3</code>. For example:
            </p><pre data-lang="terminal" class="programlisting">s3&gt; rm -rf /var/lib/mysql/*</pre><p>
              If the system variables
              <a class="link" href="innodb-storage-engine.html#sysvar_innodb_data_home_dir"><code class="literal">innodb_data_home_dir</code></a>,
              <a class="link" href="innodb-storage-engine.html#sysvar_innodb_log_group_home_dir"><code class="literal">innodb_log_group_home_dir</code></a>,
              and <a class="link" href="innodb-storage-engine.html#sysvar_innodb_undo_directory"><code class="literal">innodb_undo_directory</code></a>
              point to any directories other than the data directory,
              they should also be made empty; otherwise, the restore
              operation fails.
            </p></li><li class="listitem"><p>
              Restore backup of <code class="literal">s2</code> onto the host for
              <code class="literal">s3</code>:
            </p><pre data-lang="terminal" class="programlisting">s3&gt; <strong class="userinput"><code>mysqlbackup --defaults-file=/etc/my.cnf \
  --datadir=/var/lib/mysql \
  --backup-image=/backups/my.mbi_2206_1429  \
--backup-dir=/tmp/restore_`date +%d%m_%H%M` copy-back-and-apply-log</code></strong></pre>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Note
</div>
<p>
                The command above assumes that the binary logs and relay
                logs on <code class="literal">s2</code> and <code class="literal">s3</code>
                have the same base name and are at the same location on
                the two servers. If these conditions are not met, you
                should use the <a class="ulink" href="https://dev.mysql.com/doc/mysql-enterprise-backup/8.0/en/server-repository-options.html#option_meb_log-bin" target="_top"><code class="option">--log-bin</code></a> and
                <a class="ulink" href="https://dev.mysql.com/doc/mysql-enterprise-backup/8.0/en/server-repository-options.html#option_meb_relay-log" target="_top"><code class="option">--relay-log</code></a> options to
                restore the binary log and relay log to their original
                file paths on <code class="literal">s3</code>. For example, if you
                know that on <code class="literal">s3</code> the binary log's base
                name is <code class="literal">s3-bin</code> and the relay-log's
                base name is <code class="literal">s3-relay-bin</code>, your
                restore command should look like:
              </p><pre data-lang="terminal" class="programlisting"><strong class="userinput"><code>mysqlbackup --defaults-file=/etc/my.cnf \
  --datadir=/var/lib/mysql \
  --backup-image=/backups/my.mbi_2206_1429  \
  --log-bin=s3-bin --relay-log=s3-relay-bin \
  --backup-dir=/tmp/restore_`date +%d%m_%H%M` copy-back-and-apply-log</code></strong></pre><p>
                Being able to restore the binary log and relay log to
                the right file paths makes the restore process easier;
                if that is impossible for some reason, see
                <a class="xref" href="group-replication.html#group-replication-rebuild-member" title="Rebuild the Failed Member to Rejoin as a New Member">Rebuild the Failed Member to Rejoin as a New Member</a>.
</p>
</div>
</li></ol>
</div>
</li><li class="listitem"><p>
          <span class="emphasis"><em>Restore the <code class="filename">auto.cnf</code> file for
          s3.</em></span> To rejoin the replication group, the restored
          member <span class="emphasis"><em>must</em></span> have the same
          <a class="link" href="replication.html#sysvar_server_uuid"><code class="literal">server_uuid</code></a> it used to join
          the group before. Supply the old server UUID by copying the
          <code class="filename">auto.cnf</code> file preserved in step 2 above
          into the data directory of the restored member.
</p>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Note
</div>
<p>
            If you cannot supply the failed member's original
            <a class="link" href="replication.html#sysvar_server_uuid"><code class="literal">server_uuid</code></a> to the restored
            member by restoring its old <code class="filename">auto.cnf</code>
            file, you will have to let the restored member join the
            group as a new member; see instructions in
            <a class="xref" href="group-replication.html#group-replication-rebuild-member" title="Rebuild the Failed Member to Rejoin as a New Member">Rebuild the Failed Member to Rejoin as a New Member</a> below on
            how to do that.
</p>
</div>
</li><li class="listitem"><p>
          <span class="emphasis"><em>Restore the <code class="filename">mysqld-auto.cnf</code>
          file for s3 (only required if s3 used persistent system
          variables).</em></span> The settings for the
          <a class="xref" href="server-administration.html#persisted-system-variables" title="5.1.9.3 Persisted System Variables">Section 5.1.9.3, “Persisted System Variables”</a> that were used to
          configure the failed member must be provided to the restored
          member. These settings are to be found in the
          <code class="filename">mysqld-auto.cnf</code> file of the failed
          server, which you should have preserved in step 2 above.
          Restore the file to the data directory of the restored server.
          See
          <a class="xref" href="group-replication.html#group-replication-meb-restore-persisted-variables" title="Restoring Persisted System Variables">Restoring Persisted System Variables</a>
          on what to do if you do not have a copy of the file.
        </p></li><li class="listitem"><p>
          <span class="emphasis"><em>Start the restored server.</em></span> For example,
          on Linux distributions that use systemd:
</p><pre class="programlisting">systemctl start mysqld</pre>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Note
</div>
<p>
            If the server you are restoring is a primary member, perform
            the steps described in
            <a class="xref" href="group-replication.html#group-replication-meb-restore-primary" title="Restoring a Primary Member">Restoring a Primary Member</a>
            <span class="emphasis"><em>before starting the restored server</em></span>.
</p>
</div>
</li><li class="listitem"><p>
          <span class="emphasis"><em>Restart Group Replication.</em></span> Connect to the
          restarted <code class="literal">s3</code> using, for example, a
          <a class="link" href="programs.html#mysql" title="4.5.1 mysql — The MySQL Command-Line Client"><span class="command"><strong>mysql</strong></span></a> client, and issue the following
          command:
        </p><pre class="programlisting">mysql&gt; START GROUP_REPLICATION;</pre><p>
          Before the restored instance can become an online member of
          the group, it needs to apply any transactions that have
          happened to the group after the backup was taken; this is
          achieved using Group Replication's
          <a class="link" href="group-replication.html#group-replication-distributed-recovery" title="18.4.3 Distributed Recovery">distributed
          recovery</a> mechanism, and the process starts after the
          <a class="link" href="sql-statements.html#start-group-replication" title="13.4.3.1 START GROUP_REPLICATION Statement">START
          GROUP_REPLICATION</a> statement has been issued. To check
          the member status of the restored instance, issue:
        </p><pre class="programlisting">mysql&gt; SELECT member_host, member_port, member_state FROM performance_schema.replication_group_members;
+-------------+-------------+--------------+
| member_host | member_port | member_state |
+-------------+-------------+--------------+
| s1          |        3306 | ONLINE       |
| s2          |        3306 | ONLINE       |
| s3          |        3306 | RECOVERING   |
+-------------+-------------+--------------+</pre><p>
          This shows that <code class="literal">s3</code> is applying transactions
          to catch up with the group. Once it has caught up with the
          rest of the group, its <code class="literal">member_state</code> changes
          to <code class="literal">ONLINE</code>:
        </p><pre class="programlisting">mysql&gt; SELECT member_host, member_port, member_state FROM performance_schema.replication_group_members;
+-------------+-------------+--------------+
| member_host | member_port | member_state |
+-------------+-------------+--------------+
| s1          |        3306 | ONLINE       |
| s2          |        3306 | ONLINE       |
| s3          |        3306 | ONLINE       |
+-------------+-------------+--------------+</pre>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Note
</div>
<p>
            If the server you are restoring is a primary member, once it
            has gained synchrony with the group and become
            <code class="literal">ONLINE</code>, perform the steps described at
            the end of
            <a class="xref" href="group-replication.html#group-replication-meb-restore-primary" title="Restoring a Primary Member">Restoring a Primary Member</a> to
            revert the configuration changes you had made to the server
            before you started it.
</p>
</div>
</li></ol>
</div>
<p>
      The member has now been fully restored from the backup and
      functions as a regular member of the group.
</p>
<h4><a name="group-replication-rebuild-member"></a>Rebuild the Failed Member to Rejoin as a New Member</h4>
<p>
      Sometimes, the steps outlined above in
      <a class="xref" href="group-replication.html#group-replication-restore-failed-member" title="Restoring a Failed Member">Restoring a Failed Member</a> cannot
      be carried out because, for example, the binary log or relay log
      is corrupted, or it is just missing from the backup. In such a
      situation, use the backup to rebuild the member, and then add it
      to the group as a new member. In the steps below, we assume the
      rebuilt member will be named <code class="literal">s3</code>, like the
      failed member, and it will be run on the same host as
      <code class="literal">s3</code> was:
</p>
<div class="orderedlist">
<ol class="orderedlist" type="1"><li class="listitem"><p>
          <span class="emphasis"><em>Copy the backup of s2 onto the host for s3
          .</em></span> The exact way to copy the backup depends on the
          operating system and tools available to you. In this example
          we assume the hosts are both Linux servers and use SCP to copy
          the files between them:
        </p><pre data-lang="terminal" class="programlisting">s2/backups&gt; <strong class="userinput"><code>scp my.mbi_2206_1429 s3:/backups</code></strong></pre></li><li class="listitem"><p>
          <span class="emphasis"><em>Restore the backup.</em></span> Connect to the target
          host (the host for <code class="literal">s3</code> in this case), and
          restore the backup using MySQL Enterprise Backup. Here are the steps:
</p>
<div class="orderedlist">
<ol class="orderedlist" type="a"><li class="listitem"><p>
              Stop the corrupted server, if it is still running. For
              example, on Linux distributions that use systemd:
            </p><pre class="programlisting">s3&gt; systemctl stop mysqld</pre></li><li class="listitem"><p>
              Preserve the configuration file
              <code class="filename">mysqld-auto.cnf</code>, if it is found in
              the corrupted server's data directory, by copying it to a
              safe location outside of the data directory. This is for
              preserving the server's
              <a class="xref" href="server-administration.html#persisted-system-variables" title="5.1.9.3 Persisted System Variables">Section 5.1.9.3, “Persisted System Variables”</a>, which are
              needed later.
            </p></li><li class="listitem"><p>
              Delete all contents in the data directory of
              <code class="literal">s3</code>. For example:
            </p><pre class="programlisting">s3&gt; rm -rf /var/lib/mysql/*</pre><p>
              If the system variables
              <a class="link" href="innodb-storage-engine.html#sysvar_innodb_data_home_dir"><code class="literal">innodb_data_home_dir</code></a>,
              <a class="link" href="innodb-storage-engine.html#sysvar_innodb_log_group_home_dir"><code class="literal">innodb_log_group_home_dir</code></a>,
              and <a class="link" href="innodb-storage-engine.html#sysvar_innodb_undo_directory"><code class="literal">innodb_undo_directory</code></a>
              point to any directories other than the data directory,
              they should also be made empty; otherwise, the restore
              operation will fail.
            </p></li><li class="listitem"><p>
              Restore the backup of <code class="literal">s2</code> onto the host
              of <code class="literal">s3</code>. With this approach, we are
              rebuilding <code class="literal"><code class="literal">s3</code></code> as a
              new member, for which we do not need or do not want to use
              the old binary and relay logs in the backup; therefore, if
              these logs have been included in your backup, exclude them
              using the <a class="ulink" href="https://dev.mysql.com/doc/mysql-enterprise-backup/8.0/en/backup-capacity-options.html#option_meb_skip-binlog" target="_top"><code class="option">--skip-binlog</code></a> and
              <a class="ulink" href="https://dev.mysql.com/doc/mysql-enterprise-backup/8.0/en/backup-capacity-options.html#option_meb_skip-relaylog" target="_top"><code class="option">--skip-relaylog</code></a> options:
            </p><pre data-lang="terminal" class="programlisting">s3&gt; <strong class="userinput"><code>mysqlbackup --defaults-file=/etc/my.cnf \
  --datadir=/var/lib/mysql \
  --backup-image=/backups/my.mbi_2206_1429  \
  --backup-dir=/tmp/restore_`date +%d%m_%H%M` \
  --skip-binlog --skip-relaylog \
copy-back-and-apply-log</code></strong></pre>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Note
</div>
<p>
                If you have healthy binary log and relay logs in the
                backup that you can transfer onto the target host with
                no issues, you are recommended to follow the easier
                procedure as described in
                <a class="xref" href="group-replication.html#group-replication-restore-failed-member" title="Restoring a Failed Member">Restoring a Failed Member</a>
                above.
</p>
</div>
</li></ol>
</div>
</li><li class="listitem"><p>
          <span class="emphasis"><em>Restore the <code class="filename">mysqld-auto.cnf</code>
          file for s3 (only required if s3 used persistent system
          variables).</em></span> The settings for the
          <a class="xref" href="server-administration.html#persisted-system-variables" title="5.1.9.3 Persisted System Variables">Section 5.1.9.3, “Persisted System Variables”</a> that were used to
          configure the failed member must be provided to the restored
          server. These settings are to be found in the
          <code class="filename">mysqld-auto.cnf</code> file of the failed
          server, which you should have preserved in step 2 above.
          Restore the file to the data directory of the restored server.
          See
          <a class="xref" href="group-replication.html#group-replication-meb-restore-persisted-variables" title="Restoring Persisted System Variables">Restoring Persisted System Variables</a>
          on what to do if you do not have a copy of the file.
</p>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Note
</div>
<p>
            Do NOT restore the corrupted server's
            <code class="filename">auto.cnf</code> file to the data directory of
            the new member—when the rebuilt <code class="literal">s3</code>
            joins the group as a new member, it is going to be assigned
            a new server UUID.
</p>
</div>
</li><li class="listitem"><p>
          <span class="emphasis"><em>Start the restored server.</em></span> For example,
          on Linux distributions that use systemd:
</p><pre class="programlisting">systemctl start mysqld</pre>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Note
</div>
<p>
            If the server you are restoring is a primary member, perform
            the steps described in
            <a class="xref" href="group-replication.html#group-replication-meb-restore-primary" title="Restoring a Primary Member">Restoring a Primary Member</a>
            <span class="emphasis"><em>before starting the restored server</em></span>.
</p>
</div>
</li><li class="listitem"><p>
          <span class="emphasis"><em>Reconfigure the restored member to join Group
          Replication.</em></span> Connect to the restored server with a
          <a class="link" href="programs.html#mysql" title="4.5.1 mysql — The MySQL Command-Line Client"><span class="command"><strong>mysql</strong></span></a> client and reset the master and slave
          information with the following commands:
        </p><pre data-lang="sql" class="programlisting">mysql&gt; <strong class="userinput"><code>RESET MASTER;</code></strong></pre><pre data-lang="sql" class="programlisting">mysql&gt; <strong class="userinput"><code>RESET SLAVE ALL;</code></strong></pre><p>
          For the restored server to be able to recover automatically
          using Group Replication's built-in mechanism for
          <a class="link" href="group-replication.html#group-replication-distributed-recovery" title="18.4.3 Distributed Recovery">distributed
          recovery</a>, configure the server's
          <a class="link" href="replication.html#sysvar_gtid_executed"><code class="literal">gtid_executed</code></a> variable. To do
          this, use the <code class="filename">backup_gtid_executed.sql</code>
          file included in the backup of <code class="literal">s2</code>, which is
          usually restored under the restored member's data directory.
          Disable binary logging, use the
          <code class="filename">backup_gtid_executed.sql</code> file to
          configure <a class="link" href="replication.html#sysvar_gtid_executed"><code class="literal">gtid_executed</code></a>, and
          then re-enable binary logging by issuing the following
          statements with your <a class="link" href="programs.html#mysql" title="4.5.1 mysql — The MySQL Command-Line Client"><span class="command"><strong>mysql</strong></span></a> client:
        </p><pre data-lang="sql" class="programlisting">mysql&gt; <strong class="userinput"><code>SET SQL_LOG_BIN=OFF;</code></strong>
mysql&gt; <strong class="userinput"><code>SOURCE <em class="replaceable"><code>datadir</code></em>/backup_gtid_executed.sql</code></strong>
mysql&gt; <strong class="userinput"><code>SET SQL_LOG_BIN=ON;</code></strong>
</pre><p>
          Then, configure the
          <a class="link" href="group-replication.html#group-replication-user-credentials" title="18.2.1.3 User Credentials">Group
          Replication user credentials</a> on the member:
        </p><pre data-lang="sql" class="programlisting">mysql&gt; <strong class="userinput"><code>CHANGE MASTER TO MASTER_USER='<em class="replaceable"><code>rpl_user</code></em>', MASTER_PASSWORD='<em class="replaceable"><code>password</code></em>' / 
		FOR CHANNEL 'group_replication_recovery';</code></strong></pre></li><li class="listitem"><p>
          <span class="emphasis"><em>Restart Group Replication.</em></span> Issue the
          following command to the restored server with your
          <a class="link" href="programs.html#mysql" title="4.5.1 mysql — The MySQL Command-Line Client"><span class="command"><strong>mysql</strong></span></a> client:
        </p><pre class="programlisting">mysql&gt; <strong class="userinput"><code>START GROUP_REPLICATION;</code></strong></pre><p>
          Before the restored instance can become an online member of
          the group, it needs to apply any transactions that have
          happened to the group after the backup was taken; this is
          achieved using Group Replication's
          <a class="link" href="group-replication.html#group-replication-distributed-recovery" title="18.4.3 Distributed Recovery">distributed
          recovery</a> mechanism, and the process starts after the
          <a class="link" href="sql-statements.html#start-group-replication" title="13.4.3.1 START GROUP_REPLICATION Statement">START
          GROUP_REPLICATION</a> statement has been issued. To check
          the member status of the restored instance, issue:
        </p><pre class="programlisting">mysql&gt; SELECT member_host, member_port, member_state FROM performance_schema.replication_group_members;
+-------------+-------------+--------------+
| member_host | member_port | member_state |
+-------------+-------------+--------------+
| s3          |        3306 | RECOVERING   |
| s2          |        3306 | ONLINE       |
| s1          |        3306 | ONLINE       |
+-------------+-------------+--------------+</pre><p>
          This shows that <code class="literal">s3</code> is applying transactions
          to catch up with the group. Once it has caught up with the
          rest of the group, its <code class="literal">member_state</code> changes
          to <code class="literal">ONLINE</code>:
        </p><pre class="programlisting">mysql&gt; SELECT member_host, member_port, member_state FROM performance_schema.replication_group_members;
+-------------+-------------+--------------+
| member_host | member_port | member_state |
+-------------+-------------+--------------+
| s3          |        3306 | ONLINE       |
| s2          |        3306 | ONLINE       |
| s1          |        3306 | ONLINE       |
+-------------+-------------+--------------+</pre>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Note
</div>
<p>
            If the server you are restoring is a primary member, once it
            has gained synchrony with the group and become
            <code class="literal">ONLINE</code>, perform the steps described at
            the end of
            <a class="xref" href="group-replication.html#group-replication-meb-restore-primary" title="Restoring a Primary Member">Restoring a Primary Member</a> to
            revert the configuration changes you had made to the server
            before you started it.
</p>
</div>
</li></ol>
</div>
<p>
      The member has now been restored to the group as a new member.
    </p><p><a name="group-replication-meb-restore-persisted-variables"></a><b>Restoring Persisted System Variables. </b>
        <span class="command"><strong>mysqlbackup</strong></span> does not provide support for
        backing up or preserving
        <a class="xref" href="server-administration.html#persisted-system-variables" title="5.1.9.3 Persisted System Variables">Section 5.1.9.3, “Persisted System Variables”</a>—the file
        <code class="filename">mysqld-auto.cnf</code> is not included in a
        backup. To start the restored member with its persisted variable
        settings, you need to do one of the following:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
          Preserve a copy of the <code class="filename">mysqld-auto.cnf</code>
          file from the corrupted server, and copy it to the restored
          server's data directory.
        </p></li><li class="listitem"><p>
          Copy the <code class="filename">mysqld-auto.cnf</code> file from
          another member of the group into the restored server's data
          directory, if that member has the same persisted system
          variable settings as the corrupted member.
        </p></li><li class="listitem"><p>
          After the restored server is started and before you restart
          Group Replication, set all the system variables manually to
          their persisted values through a <a class="link" href="programs.html#mysql" title="4.5.1 mysql — The MySQL Command-Line Client"><span class="command"><strong>mysql</strong></span></a>
          client.
</p></li></ul>
</div>
<p><a name="group-replication-meb-restore-primary"></a><b>Restoring a Primary Member. </b>
        If the restored member is a primary in the group, care must be
        taken to prevent writes to the restored database during the
        Group Replication distributed recovery process. Depending on how
        the group is accessed by clients, there is a possibility of DML
        statements being executed on the restored member once it becomes
        accessible on the network, prior to the member finishing its
        catch-up on the activities it has missed while off the group. To
        avoid this, <span class="emphasis"><em>before starting the restored
        server</em></span>, configure the following system variables in
        the server option file:
      </p><pre data-lang="ini" class="programlisting">group_replication_start_on_boot=OFF
super_read_only=ON
event_scheduler=OFF</pre><p>
      These settings ensure that the member becomes read-only at startup
      and that the event scheduler is turned off while the member is
      catching up with the group during the distributed recovery
      process. Adequate error handling must also be configured on the
      clients, as they will be prevented temporarily from performing DML
      operations during this period on the restored member. Once the
      restore process is fully completed and the restored member is
      in-sync with the rest of the group, revert those changes; restart
      the event scheduler:
    </p><pre data-lang="sql" class="programlisting">mysql&gt; <strong class="userinput"><code>SET global event_scheduler=ON;</code></strong>
</pre><p>
      Edit the following system variables in the member's option
      file, so things are correctly configured for the next startup:
    </p><pre data-lang="ini" class="programlisting">group_replication_start_on_boot=ON
super_read_only=OFF
event_scheduler=ON</pre>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a name="group-replication-security"></a>18.5 Group Replication Security</h2>

</div>

</div>

</div>
<div class="toc">
<dl class="toc"><dt><span class="section"><a href="group-replication.html#group-replication-ip-address-whitelisting">18.5.1 Group Replication IP Address Whitelisting</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-secure-socket-layer-support-ssl">18.5.2 Group Replication Secure Socket Layer (SSL) Support</a></span></dt></dl>
</div>
<a class="indexterm" name="idm46444258893488"></a><p>
    This section explains how to secure a group, securing the
    connections between members of a group, or by establishing a
    security perimeter using IP address whitelisting.
</p>
<div class="section">

<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="group-replication-ip-address-whitelisting"></a>18.5.1 Group Replication IP Address Whitelisting</h3>
</div>
</div>
</div>
<a class="indexterm" name="idm46444258890272"></a><a class="indexterm" name="idm46444258888784"></a><a class="indexterm" name="idm46444258887296"></a><p>
      The Group Replication plugin has a configuration option to
      determine from which hosts an incoming Group Communication System
      connection can be accepted. This option is called
      <a class="link" href="group-replication.html#sysvar_group_replication_ip_whitelist"><code class="literal">group_replication_ip_whitelist</code></a>.
      If you set this option on a server s1, then when server s2 is
      establishing a connection to s1 for the purpose of engaging group
      communication, s1 first checks the whitelist before accepting the
      connection from s2. If s2 is in the whitelist, then s1 accepts the
      connection, otherwise s1 rejects the connection attempt by s2.
    </p><p>
      If you do not specify a whitelist explicitly, the group
      communication engine (XCom) automatically scans active interfaces
      on the host, and identifies those with addresses on private
      subnetworks. These addresses and the <code class="literal">localhost</code>
      IP address for IPv4 and (from MySQL 8.0.14) IPv6 are used to
      create an automatic Group Replication whitelist. The automatic
      whitelist therefore includes any IP addresses found for the host
      in the following ranges:
    </p><pre data-lang="none" class="programlisting">IPv4 (as defined in RFC 1918)
10/8 prefix       (10.0.0.0 - 10.255.255.255) - Class A 
172.16/12 prefix  (172.16.0.0 - 172.31.255.255) - Class B
192.168/16 prefix (192.168.0.0 - 192.168.255.255) - Class C

IPv6 (as defined in RFC 4193 and RFC 5156)
fc00:/7 prefix    - unique-local addresses
fe80::/10 prefix  - link-local unicast addresses

127.0.0.1 - localhost for IPv4
::1       - localhost for IPv6</pre><p>
      An entry is added to the error log stating the addresses that have
      been whitelisted automatically for the host.
    </p><p>
      The automatic whitelist of private addresses cannot be used for
      connections from servers outside the private network, so a server,
      even if it has interfaces on public IPs, does not by default allow
      Group Replication connections from external hosts. For Group
      Replication connections between server instances that are on
      different machines, you must provide public IP addresses and
      specify these as an explicit whitelist. If you specify any entries
      for the whitelist, the private and <code class="literal">localhost</code>
      addresses are not added automatically, so if you use any of these,
      you must specify them explicitly.
    </p><p>
      To specify a whitelist manually, use the
      <a class="link" href="group-replication.html#sysvar_group_replication_ip_whitelist"><code class="literal">group_replication_ip_whitelist</code></a>
      option. You cannot change the whitelist on a server while it is an
      active member of a replication group. If the member is active, you
      must issue a <a class="link" href="sql-statements.html#stop-group-replication" title="13.4.3.2 STOP GROUP_REPLICATION Statement"><code class="literal">STOP GROUP_REPLICATION</code></a>
      statement before changing the whitelist, and a
      <a class="link" href="sql-statements.html#start-group-replication" title="13.4.3.1 START GROUP_REPLICATION Statement"><code class="literal">START GROUP_REPLICATION</code></a> statement
      afterwards.
    </p><p>
      In the whitelist, you can specify any combination of the
      following:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
          IPv4 addresses (for example, <code class="literal">198.51.100.44</code>)
        </p></li><li class="listitem"><p>
          IPv4 addresses with CIDR notation (for example,
          <code class="literal">192.0.2.21/24</code>)
        </p></li><li class="listitem"><p>
          IPv6 addresses, from MySQL 8.0.14 (for example,
          <code class="literal">2001:db8:85a3:8d3:1319:8a2e:370:7348</code>)
        </p></li><li class="listitem"><p>
          IPv6 addresses with CIDR notation, from MySQL 8.0.14 (for
          example, <code class="literal">2001:db8:85a3:8d3::/64</code>)
        </p></li><li class="listitem"><p>
          Host names (for example, <code class="literal">example.org</code>)
        </p></li><li class="listitem"><p>
          Host names with CIDR notation (for example,
          <code class="literal">www.example.com/24</code>)
</p></li></ul>
</div>
<p>
      Before MySQL 8.0.14, host names could only resolve to IPv4
      addresses. From MySQL 8.0.14, host names can resolve to IPv4
      addresses, IPv6 addresses, or both. If a host name resolves to
      both an IPv4 and an IPv6 address, the IPv4 address is always used
      for Group Replication connections. You can use CIDR notation in
      combination with host names or IP addresses to whitelist a block
      of IP addresses with a particular network prefix, but do ensure
      that all the IP addresses in the specified subnet are under your
      control.
    </p><p>
      You must stop and restart Group Replication on a member in order
      to change its whitelist. A comma must separate each entry in the
      whitelist. For example:
    </p><pre data-lang="sql" class="programlisting">mysql&gt; STOP GROUP_REPLICATION;
mysql&gt; SET GLOBAL group_replication_ip_whitelist="192.0.2.21/24,198.51.100.44,203.0.113.0/24,2001:db8:85a3:8d3:1319:8a2e:370:7348,example.org,www.example.com/24";
mysql&gt; START GROUP_REPLICATION;</pre><p>
      The whitelist must contain the IP address or host name that is
      specified in each member's
      <a class="link" href="group-replication.html#sysvar_group_replication_local_address"><code class="literal">group_replication_local_address</code></a>
      system variable. This address is not the same as the MySQL server
      SQL protocol host and port, and is not specified in the
      <a class="link" href="server-administration.html#sysvar_bind_address"><code class="literal">bind_address</code></a> system variable for
      the server instance. If a host name used as the Group Replication
      local address for a server instance resolves to both an IPv4 and
      an IPv6 address, the IPv4 address is preferred for Group
      Replication connections.
    </p><p>
      To join a replication group, a server needs to be whitelisted on
      the seed member to which it makes the request to join the group.
      Typically, this would be the bootstrap member for the replication
      group, but it can be any of the servers listed by the
      <a class="link" href="group-replication.html#sysvar_group_replication_group_seeds"><code class="literal">group_replication_group_seeds</code></a>
      option in the configuration for the server joining the group. If
      any of the seed members for the group are listed in the
      <a class="link" href="group-replication.html#sysvar_group_replication_group_seeds"><code class="literal">group_replication_group_seeds</code></a>
      option with an IPv6 address when a joining member has an IPv4
      <a class="link" href="group-replication.html#sysvar_group_replication_local_address"><code class="literal">group_replication_local_address</code></a>,
      or the reverse, you must also set up and whitelist an alternative
      address for the joining member for the protocol offered by the
      seed member (or a host name that resolves to an address for that
      protocol). This is because when a server joins a replication
      group, it must make the initial contact with the seed member using
      the protocol that the seed member advertises in the
      <a class="link" href="group-replication.html#sysvar_group_replication_group_seeds"><code class="literal">group_replication_group_seeds</code></a>
      option, whether that is IPv4 or IPv6. If a joining member does not
      have a whitelisted address for the appropriate protocol, its
      connection attempt is refused. For more information on managing
      mixed IPv4 and IPv6 replication groups, see
      <a class="xref" href="group-replication.html#group-replication-ipv6" title="18.4.5 Support For IPv6 And For Mixed IPv6 And IPv4 Groups">Section 18.4.5, “Support For IPv6 And For Mixed IPv6 And IPv4 Groups”</a>.
    </p><p>
      When a replication group is reconfigured (for example, when a new
      primary is elected or a member joins or leaves), the group members
      re-establish connections between themselves. If a group member is
      only whitelisted by servers that are no longer part of the
      replication group after the reconfiguration, it is unable to
      reconnect to the remaining servers in the replication group that
      do not whitelist it. To avoid this scenario entirely, specify the
      same whitelist for all servers that are members of the replication
      group.
</p>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Note
</div>
<p>
        It is possible to configure different whitelists on different
        group members according to your security requirements, for
        example, in order to keep different subnets separate. If you
        need to configure different whitelists to meet your security
        requirements, ensure that there is sufficient overlap between
        the whitelists in the replication group to maximize the
        possibility of servers being able to reconnect in the absence of
        their original seed member.
</p>
</div>
<p>
      For host names, name resolution takes place only when a connection
      request is made by another server. A host name that cannot be
      resolved is not considered for whitelist validation, and a warning
      message is written to the error log. Forward-confirmed reverse DNS
      (FCrDNS) verification is carried out for resolved host names.
</p>
<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Warning
</div>
<p>
        Host names are inherently less secure than IP addresses in a
        whitelist. FCrDNS verification provides a good level of
        protection, but can be compromised by certain types of attack.
        Specify host names in your whitelist only when strictly
        necessary, and ensure that all components used for name
        resolution, such as DNS servers, are maintained under your
        control. You can also implement name resolution locally using
        the hosts file, to avoid the use of external components.
</p>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="group-replication-secure-socket-layer-support-ssl"></a>18.5.2 Group Replication Secure Socket Layer (SSL) Support</h3>

</div>

</div>

</div>
<a class="indexterm" name="idm46444258844352"></a><a class="indexterm" name="idm46444258842848"></a><p>
      Group communication connections and distributed recovery
      connections can be secured using SSL. The following sections
      explain how to configure connections.
</p>
<div class="simplesect">

<div class="titlepage">
<div>

<div class="simple">
<h4 class="title"><a name="group-replication-configuring-ssl-for-group-communication"></a>Configuring SSL for Group Communication</h4>
</div>
</div>
</div>
<p>
        Secure sockets can be used for group communication connections
        between members of a group. The Group Replication system
        variable
        <a class="link" href="group-replication.html#sysvar_group_replication_ssl_mode"><code class="literal">group_replication_ssl_mode</code></a> is
        used to activate the use of SSL for group communication
        connections and specify the security mode for the connections.
        The default setting means that SSL is not used. The option has
        the following possible values:
</p>
<div class="table">
<a name="idm46444258837424"></a><p class="title"><b>Table 18.2 group_replication_ssl_mode configuration values</b></p>
<div class="table-contents">
<table summary="Lists the possible values for group_replication_ssl_mode and describes their effect on how replication group members connect to each other."><col width="35%"><col width="65%"><thead><tr>
            <th scope="col"><p>
                Value
              </p></th>
            <th scope="col"><p>
                Description
              </p></th>
          </tr></thead><tbody><tr>
            <td scope="row"><p>
                DISABLED
              </p></td>
            <td><p>
                Establish an unencrypted connection (the default).
              </p></td>
          </tr><tr>
            <td scope="row"><p>
                REQUIRED
              </p></td>
            <td><p>
                Establish a secure connection if the server supports
                secure connections.
              </p></td>
          </tr><tr>
            <td scope="row"><p>
                VERIFY_CA
              </p></td>
            <td><p>
                Like REQUIRED, but additionally verify the server TLS
                certificate against the configured Certificate Authority
                (CA) certificates.
              </p></td>
          </tr><tr>
            <td scope="row"><p>
                VERIFY_IDENTITY
              </p></td>
            <td><p>
                Like VERIFY_CA, but additionally verify that the server
                certificate matches the host to which the connection is
                attempted.
              </p></td>
</tr></tbody></table>
</div>

</div>
<br class="table-break"><p>
        The remainder of the configuration for Group Replication's group
        communication connections is taken from the server's SSL
        configuration. For more information on the options for
        configuring the server SSL, see
        <a class="xref" href="programs.html#encrypted-connection-options" title="Command Options for Encrypted Connections">Command Options for Encrypted Connections</a>. The server SSL
        options that are applied to Group Replication's group
        communication connections are as follows:
</p>
<div class="table">
<a name="idm46444258818128"></a><p class="title"><b>Table 18.3 SSL Options</b></p>
<div class="table-contents">
<table summary="Lists the server configuration options for SSL and describes their effect on the configuration of the Group Replication plugin for SSL."><col width="35%"><col width="65%"><thead><tr>
            <th scope="col"><p>
                Server Configuration
              </p></th>
            <th scope="col"><p>
                Description
              </p></th>
          </tr></thead><tbody><tr>
            <td scope="row"><p>
                <a class="link" href="server-administration.html#sysvar_ssl_key"><code class="literal">ssl_key</code></a>
              </p></td>
            <td><p>
                The path name of the SSL private key file in PEM format.
                On the client side, this is the client private key. On
                the server side, this is the server private key.
              </p></td>
          </tr><tr>
            <td scope="row"><p>
                <a class="link" href="server-administration.html#sysvar_ssl_cert"><code class="literal">ssl_cert</code></a>
              </p></td>
            <td><p>
                The path name of the SSL public key certificate file in
                PEM format. On the client side, this is the client
                public key certificate. On the server side, this is the
                server public key certificate.
              </p></td>
          </tr><tr>
            <td scope="row"><p>
                <a class="link" href="server-administration.html#sysvar_ssl_ca"><code class="literal">ssl_ca</code></a>
              </p></td>
            <td><p>
                The path name of the Certificate Authority (CA)
                certificate file in PEM format.
              </p></td>
          </tr><tr>
            <td scope="row"><p>
                <a class="link" href="server-administration.html#sysvar_ssl_capath"><code class="literal">ssl_capath</code></a>
              </p></td>
            <td><p>
                The path name of the directory that contains trusted SSL
                certificate authority (CA) certificate files in PEM
                format.
              </p></td>
          </tr><tr>
            <td scope="row"><p>
                <a class="link" href="server-administration.html#sysvar_ssl_crl"><code class="literal">ssl_crl</code></a>
              </p></td>
            <td><p>
                The path name of the file containing certificate
                revocation lists in PEM format.
              </p></td>
          </tr><tr>
            <td scope="row"><p>
                <a class="link" href="server-administration.html#sysvar_ssl_crlpath"><code class="literal">ssl_crlpath</code></a>
              </p></td>
            <td><p>
                The path name of the directory that contains certificate
                revocation list files in PEM format.
              </p></td>
          </tr><tr>
            <td scope="row"><p>
                <a class="link" href="server-administration.html#sysvar_ssl_cipher"><code class="literal">ssl_cipher</code></a>
              </p></td>
            <td><p>
                A list of permissible ciphers for encrypted connections.
              </p></td>
          </tr><tr>
            <td scope="row"><p>
                <a class="link" href="server-administration.html#sysvar_tls_version"><code class="literal">tls_version</code></a>
              </p></td>
            <td><p>
                A list of the TLS protocols the server permits for
                encrypted connections.
              </p></td>
          </tr><tr>
            <td scope="row"><p>
                <a class="link" href="server-administration.html#sysvar_tls_ciphersuites"><code class="literal">tls_ciphersuites</code></a>
              </p></td>
            <td><p>
                Which TLSv1.3 ciphersuites the server permits for
                encrypted connections.
              </p></td>
</tr></tbody></table>
</div>

</div>
<br class="table-break">
<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Important
</div>

<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              Support for the TLSv1.3 protocol is available in MySQL
              Server as of MySQL 8.0.16, provided that MySQL was
              compiled using OpenSSL 1.1.1 or higher. Group Replication
              supports TLSv1.3 from MySQL 8.0.18. In MySQL 8.0.16 and
              MySQL 8.0.17, if the server supports TLSv1.3, the protocol
              is not supported in the group communication engine and
              cannot be used by Group Replication.
            </p></li><li class="listitem"><p>
              In the list of TLS protocols specified in the
              <a class="link" href="server-administration.html#sysvar_tls_version"><code class="literal">tls_version</code></a> system
              variable, ensure the specified versions are contiguous
              (for example, <code class="literal">TLSv1,TLSv1.1,TLSv1.2</code>).
              If there are any gaps in the list of protocols (for
              example, if you specified
              <code class="literal">TLSv1,TLSv1.2</code>, omitting TLS 1.1) Group
              Replication might be unable to make group communication
              connections.
            </p></li><li class="listitem"><p>
              In MySQL 8.0.18, TLSv1.3 can be used in Group Replication
              for the distributed recovery connection, but the
              <a class="link" href="group-replication.html#sysvar_group_replication_recovery_tls_version"><code class="literal">group_replication_recovery_tls_version</code></a>
              and
              <a class="link" href="group-replication.html#sysvar_group_replication_recovery_tls_ciphersuites"><code class="literal">group_replication_recovery_tls_ciphersuites</code></a>
              system variables are not available. The donor servers must
              therefore permit the use of at least one TLSv1.3
              ciphersuite that is enabled by default, as listed in
              <a class="xref" href="security.html#encrypted-connection-protocols-ciphers" title="6.3.2 Encrypted Connection TLS Protocols and Ciphers">Section 6.3.2, “Encrypted Connection TLS Protocols and Ciphers”</a>.
              From MySQL 8.0.19, you can use the options to configure
              client support for any selection of ciphersuites,
              including only non-default ciphersuites if you want.
</p></li></ul>
</div>

</div>
<p>
        In a replication group, OpenSSL negotiates the use of the
        highest TLS protocol that is supported by all members. A joining
        member that is configured to use only TLSv1.3
        (<a class="link" href="server-administration.html#sysvar_tls_version"><code class="literal">tls_version=TLSv1.3</code></a>) cannot
        join a replication group where any existing member does not
        support TLSv1.3, because the group members in that case are
        using a lower TLS protocol version. To join the member to the
        group, you must configure the joining member to also permit the
        use of lower TLS protocol versions supported by the existing
        group members. Conversely, if a joining member does not support
        TLSv1.3, but the existing group members all do and are using
        that version for connections to each other, the member can join
        if the existing group members already permit the use of a
        suitable lower TLS protocol version, or if you configure them to
        do so. In that situation, OpenSSL uses a lower TLS protocol
        version for the connections from each member to the joining
        member. Each member's connections to other existing members
        continue to use the highest available protocol that both members
        support.
      </p><p>
        From MySQL 8.0.16, you can change the
        <a class="link" href="server-administration.html#sysvar_tls_version"><code class="literal">tls_version</code></a> system variable at
        runtime to alter the list of permitted TLS protocol versions for
        the server. Note that for Group Replication, the
        <a class="link" href="sql-statements.html#alter-instance-reload-tls"><code class="literal">ALTER INSTANCE RELOAD TLS</code></a>
        statement, which reconfigures the server's TLS context from the
        current values of the system variables that define the context,
        does not change the TLS context for Group Replication's group
        communication connection while Group Replication is running. To
        apply the reconfiguration to these connections, you must issue
        <a class="link" href="sql-statements.html#stop-group-replication" title="13.4.3.2 STOP GROUP_REPLICATION Statement"><code class="literal">STOP GROUP_REPLICATION</code></a> followed
        by <a class="link" href="sql-statements.html#start-group-replication" title="13.4.3.1 START GROUP_REPLICATION Statement"><code class="literal">START GROUP_REPLICATION</code></a> to
        restart Group Replication on the member or members where you
        changed the <a class="link" href="server-administration.html#sysvar_tls_version"><code class="literal">tls_version</code></a> system
        variable. Similarly, if you want to make all members of a group
        change to using a higher or lower TLS protocol version, you must
        carry out a rolling restart of Group Replication on the members
        after changing the list of permitted TLS protocol versions, so
        that OpenSSL negotiates the use of the higher TLS protocol
        version when the rolling restart is completed. For instructions
        to change the list of permitted TLS protocol versions at
        runtime, see
        <a class="xref" href="security.html#encrypted-connection-protocols-ciphers" title="6.3.2 Encrypted Connection TLS Protocols and Ciphers">Section 6.3.2, “Encrypted Connection TLS Protocols and Ciphers”</a> and
        <a class="xref" href="security.html#using-encrypted-connections-server-side-runtime-configuration" title="Server-Side Runtime Configuration and Monitoring for Encrypted Connections">Server-Side Runtime Configuration and Monitoring for Encrypted
        Connections</a>.
      </p><p>
        The following example shows a section from a
        <code class="literal">my.cnf</code> file that configures SSL on a server,
        and activates SSL for Group Replication group communication
        connections:
      </p><pre data-lang="ini" class="programlisting">[mysqld]
ssl_ca = "cacert.pem"
ssl_capath = "/.../ca_directory"
ssl_cert = "server-cert.pem"
ssl_cipher = "DHE-RSA-AEs256-SHA"
ssl_crl = "crl-server-revoked.crl"
ssl_crlpath = "/.../crl_directory"
ssl_key = "server-key.pem"
group_replication_ssl_mode= REQUIRED</pre>
<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Important
</div>
<p>
          The <a class="link" href="sql-statements.html#alter-instance-reload-tls"><code class="literal">ALTER INSTANCE RELOAD TLS</code></a>
          statement, which reconfigures the server's TLS context from
          the current values of the system variables that define the
          context, does not change the TLS context for Group
          Replication's group communication connections while Group
          Replication is running. To apply the reconfiguration to these
          connections, you must issue <a class="link" href="sql-statements.html#stop-group-replication" title="13.4.3.2 STOP GROUP_REPLICATION Statement"><code class="literal">STOP
          GROUP_REPLICATION</code></a> followed by
          <a class="link" href="sql-statements.html#start-group-replication" title="13.4.3.1 START GROUP_REPLICATION Statement"><code class="literal">START GROUP_REPLICATION</code></a> to
          restart Group Replication.
</p>
</div>

</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h4 class="title"><a name="group-replication-configuring-ssl-for-recovery"></a>Configuring SSL for Distributed Recovery</h4>

</div>

</div>

</div>
<p>
        When a member joins the group, distributed recovery is carried
        out using a combination of a remote cloning operation, if
        available and appropriate, and an asynchronous replication
        connection. Both methods of state transfer require a replication
        user that has been set up for distributed recovery, as described
        in <a class="xref" href="group-replication.html#group-replication-user-credentials" title="18.2.1.3 User Credentials">Section 18.2.1.3, “User Credentials”</a>. A
        replication user that requires an SSL connection must be created
        <span class="emphasis"><em>before</em></span> the server joining the group (the
        joining member) connects to the donor. Typically, this is set up
        at the time you are provisioning a server to join the group.
      </p><p>
        To create a replication user for distributed recovery that
        requires an SSL connection, issue these statements:
      </p><pre data-lang="sql" class="programlisting">donor&gt; <strong class="userinput"><code>SET SQL_LOG_BIN=0;</code></strong>
donor&gt; <strong class="userinput"><code>CREATE USER '<em class="replaceable"><code>rec_ssl_user</code></em>'@'%' REQUIRE SSL;</code></strong>
donor&gt; <strong class="userinput"><code>GRANT replication slave ON *.* TO '<em class="replaceable"><code>rec_ssl_user</code></em>'@'%';</code></strong>
donor&gt; <strong class="userinput"><code>GRANT BACKUP_ADMIN ON *.* TO '<em class="replaceable"><code>rec_ssl_user</code></em>'@'%';</code></strong>
donor&gt; <strong class="userinput"><code>SET SQL_LOG_BIN=1;</code></strong></pre><p>
        Assuming that all servers already in the group have a
        replication user set up to use SSL, you configure joining
        members to use those credentials when connecting to the donor by
        configuring the Group Replication recovery channel to use the
        credentials, as follows:
      </p><pre data-lang="sql" class="programlisting">new_member&gt; <strong class="userinput"><code>CHANGE MASTER TO MASTER_USER="<em class="replaceable"><code>rec_ssl_user</code></em>" FOR CHANNEL "group_replication_recovery";</code></strong>
</pre><p>
        To configure secure distributed recovery connections, use Group
        Replication's dedicated distributed recovery SSL options. These
        options correspond to the server SSL options that are used for
        group communication connections, but they are only applied for
        distributed recovery connections. By default, distributed
        recovery connections do not use SSL, even if you activated SSL
        for group communication connections, and the server SSL options
        are not applied for distributed recovery connections. You must
        configure these connections separately.
      </p><p>
        If a remote cloning operation is used as part of distributed
        recovery, Group Replication automatically configures the clone
        plugin's SSL options to match your settings for the distributed
        recovery SSL options. (For details of how the clone plugin uses
        SSL, see <a class="xref" href="server-administration.html#clone-plugin-remote-ssl" title="Configuring an Encrypted Connection for Cloning">Configuring an Encrypted Connection for Cloning</a>.)
      </p><p>
        The distributed recovery SSL options are as follows:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            <a class="link" href="group-replication.html#sysvar_group_replication_recovery_use_ssl"><code class="literal">group_replication_recovery_use_ssl</code></a>:
            Set to <code class="literal">ON</code> to make Group Replication use
            SSL for distributed recovery connections, including remote
            cloning operations and state transfer from a donor's binary
            log.
          </p></li><li class="listitem"><p>
            <a class="link" href="group-replication.html#sysvar_group_replication_recovery_ssl_ca"><code class="literal">group_replication_recovery_ssl_ca</code></a>:
            The path name of the Certificate Authority (CA) file to use
            for distributed recovery connections. Group Replication
            automatically configures the clone SSL option
            <a class="link" href="server-administration.html#sysvar_clone_ssl_ca"><code class="literal">clone_ssl_ca</code></a> to match this.
          </p><p>
            <a class="link" href="group-replication.html#sysvar_group_replication_recovery_ssl_capath"><code class="literal">group_replication_recovery_ssl_capath</code></a>:
            The path name of a directory that contains trusted SSL
            certificate authority (CA) certificate files.
          </p></li><li class="listitem"><p>
            <a class="link" href="group-replication.html#sysvar_group_replication_recovery_ssl_cert"><code class="literal">group_replication_recovery_ssl_cert</code></a>:
            The path name of the SSL public key certificate file to use
            for distributed recovery connections. Group Replication
            automatically configures the clone SSL option
            <a class="link" href="server-administration.html#sysvar_clone_ssl_cert"><code class="literal">clone_ssl_cert</code></a> to match
            this.
          </p></li><li class="listitem"><p>
            <a class="link" href="group-replication.html#sysvar_group_replication_recovery_ssl_key"><code class="literal">group_replication_recovery_ssl_key</code></a>:
            The path name of the SSL private key file to use for
            distributed recovery connections. Group Replication
            automatically configures the clone SSL option
            <a class="link" href="server-administration.html#sysvar_clone_ssl_cert"><code class="literal">clone_ssl_cert</code></a> to match
            this.
          </p></li><li class="listitem"><p>
            <a class="link" href="group-replication.html#sysvar_group_replication_recovery_ssl_verify_server_cert"><code class="literal">group_replication_recovery_ssl_verify_server_cert</code></a>:
            Makes the distributed recovery connection check the server's
            Common Name value in the donor sent certificate. Setting
            this option to <code class="literal">ON</code> is the equivalent for
            distributed recovery connections of setting
            <code class="literal">VERIFY_IDENTITY</code> for the
            <a class="link" href="group-replication.html#sysvar_group_replication_ssl_mode"><code class="literal">group_replication_ssl_mode</code></a>
            option for group communication connections.
          </p></li><li class="listitem"><p>
            <a class="link" href="group-replication.html#sysvar_group_replication_recovery_ssl_crl"><code class="literal">group_replication_recovery_ssl_crl</code></a>:
            The path name of a file containing certificate revocation
            lists.
          </p></li><li class="listitem"><p>
            <a class="link" href="group-replication.html#sysvar_group_replication_recovery_ssl_crlpath"><code class="literal">group_replication_recovery_ssl_crlpath</code></a>:
            The path name of a directory containing certificate
            revocation lists.
          </p></li><li class="listitem"><p>
            <a class="link" href="group-replication.html#sysvar_group_replication_recovery_ssl_cipher"><code class="literal">group_replication_recovery_ssl_cipher</code></a>:
            A list of permissible ciphers for connection encryption for
            the distributed recovery connection. Specify a list of one
            or more cipher names, separated by colons. For information
            about which encryption ciphers MySQL supports, see
            <a class="xref" href="security.html#encrypted-connection-protocols-ciphers" title="6.3.2 Encrypted Connection TLS Protocols and Ciphers">Section 6.3.2, “Encrypted Connection TLS Protocols and Ciphers”</a>.
          </p></li><li class="listitem"><p>
            <a class="link" href="group-replication.html#sysvar_group_replication_recovery_tls_version"><code class="literal">group_replication_recovery_tls_version</code></a>:
            A comma-separated list of one or more permitted TLS
            protocols for connection encryption when this server
            instance is the client in the distributed recovery
            connection, that is, the joining member. Ensure the
            specified versions are contiguous (for example,
            <span class="quote">“<span class="quote"><code class="literal">TLSv1,TLSv1.1,TLSv1.2</code></span>”</span>). If
            this system variable is not set, the default
            <span class="quote">“<span class="quote"><code class="literal">TLSv1,TLSv1.1,TLSv1.2,TLSv1.3</code></span>”</span>
            is used. The group members involved in each distributed
            recovery connection as the client (joining member) and
            server (donor) negotiate the highest protocol version that
            they are both set up to support. This system variable is
            available from MySQL 8.0.19.
          </p></li><li class="listitem"><p>
            <a class="link" href="group-replication.html#sysvar_group_replication_recovery_tls_ciphersuites"><code class="literal">group_replication_recovery_tls_ciphersuites</code></a>:
            A colon-separated list of one or more permitted ciphersuites
            when TLSv1.3 is used for connection encryption for the
            distributed recovery connection, and this server instance is
            the client in the distributed recovery connection, that is,
            the joining member. If this system variable is set to
            <code class="literal">NULL</code> when TLSv1.3 is used (which is the
            default if you do not set the system variable), the
            ciphersuites that are enabled by default are allowed, as
            listed in
            <a class="xref" href="security.html#encrypted-connection-protocols-ciphers" title="6.3.2 Encrypted Connection TLS Protocols and Ciphers">Section 6.3.2, “Encrypted Connection TLS Protocols and Ciphers”</a>. If
            this system variable is set to the empty string, no
            ciphersuites are allowed, and TLSv1.3 will therefore not be
            used. This system variable is available from MySQL 8.0.19.
</p></li></ul>
</div>
<p>
        For example, issuing the following statements enables the use of
        SSL for distributed recovery connections, and identifies the
        paths to the certificate authority (CA) file, the public key
        certificate file, and the private key file that must be used for
        those connections:
      </p><pre data-lang="sql" class="programlisting">new_member&gt; <strong class="userinput"><code>SET GLOBAL group_replication_recovery_use_ssl=1;</code></strong>
new_member&gt; <strong class="userinput"><code>SET GLOBAL group_replication_recovery_ssl_ca= '.../cacert.pem';</code></strong>
new_member&gt; <strong class="userinput"><code>SET GLOBAL group_replication_recovery_ssl_cert= '.../client-cert.pem';</code></strong>
new_member&gt; <strong class="userinput"><code>SET GLOBAL group_replication_recovery_ssl_key= '.../client-key.pem';</code></strong></pre>
</div>

</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a name="group-replication-performance"></a>18.6 Group Replication Performance</h2>

</div>

</div>

</div>
<div class="toc">
<dl class="toc"><dt><span class="section"><a href="group-replication.html#group-replication-fine-tuning-the-group-communication-thread">18.6.1 Fine Tuning the Group Communication Thread</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-flow-control">18.6.2 Flow Control</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-message-compression">18.6.3 Message Compression</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-performance-message-fragmentation">18.6.4 Message Fragmentation</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-performance-xcom-cache">18.6.5 XCom Cache Management</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-responses-failure">18.6.6 Responses to Failure Detection and Network Partitioning</a></span></dt></dl>
</div>
<a class="indexterm" name="idm46444258686976"></a><p>
    This section explains how to use the available configuration options
    to gain the best performance from your replication group.
</p>
<div class="section">

<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="group-replication-fine-tuning-the-group-communication-thread"></a>18.6.1 Fine Tuning the Group Communication Thread</h3>
</div>
</div>
</div>
<a class="indexterm" name="idm46444258683648"></a><a class="indexterm" name="idm46444258682128"></a><p>
      The group communication thread (GCT) runs in a loop while the
      Group Replication plugin is loaded. The GCT receives messages from
      the group and from the plugin, handles quorum and failure
      detection related tasks, sends out some keep alive messages and
      also handles the incoming and outgoing transactions from/to the
      server/group. The GCT waits for incoming messages in a queue. When
      there are no messages, the GCT waits. By configuring this wait to
      be a little longer (doing an active wait) before actually going to
      sleep can prove to be beneficial in some cases. This is because
      the alternative is for the operating system to switch out the GCT
      from the processor and do a context switch.
    </p><p>
      To force the GCT to do an active wait, use the
      <a class="link" href="group-replication.html#sysvar_group_replication_poll_spin_loops"><code class="literal">group_replication_poll_spin_loops</code></a>
      option, which makes the GCT loop, doing nothing relevant for the
      configured number of loops, before actually polling the queue for
      the next message.
    </p><p>
      For example:
</p><pre data-lang="sql" class="programlisting">mysql&gt; SET GLOBAL group_replication_poll_spin_loops= 10000;</pre>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="group-replication-flow-control"></a>18.6.2 Flow Control</h3>

</div>

</div>

</div>
<div class="toc">
<dl class="toc"><dt><span class="section"><a href="group-replication.html#group-replication-probes-and-statistics">18.6.2.1 Probes and Statistics</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-throttling">18.6.2.2 Group Replication Throttling</a></span></dt></dl>
</div>
<a class="indexterm" name="idm46444258674880"></a><p>
      Group Replication ensures that a transaction only commits after a
      majority of the members in a group have received it and agreed on
      the relative order between all transactions that were sent
      concurrently. This approach works well if the total number of
      writes to the group does not exceed the write capacity of any
      member in the group. If it does and some of the members have less
      write throughput than others, particularly less than the writer
      members, those members can start lagging behind of the writers.
    </p><p>
      Having some members lagging behind the group brings some
      problematic consequences, particularly, the reads on such members
      may externalize very old data. Depending on why the member is
      lagging behind, other members in the group may have to save more
      or less replication context to be able to fulfil potential data
      transfer requests from the slow member.
    </p><p>
      There is however a mechanism in the replication protocol to avoid
      having too much distance, in terms of transactions applied,
      between fast and slow members. This is known as the flow control
      mechanism. It tries to address several goals:
</p>
<div class="orderedlist">
<ol class="orderedlist" type="1"><li class="listitem"><p>
          to keep the members close enough to make buffering and
          de-synchronization between members a small problem;
        </p></li><li class="listitem"><p>
          to adapt quickly to changing conditions like different
          workloads or more writers in the group;
        </p></li><li class="listitem"><p>
          to give each member a fair share of the available write
          capacity;
        </p></li><li class="listitem"><p>
          to not reduce throughput more than strictly necessary to avoid
          wasting resources.
</p></li></ol>
</div>
<p>
      Given the design of Group Replication, the decision whether to
      throttle or not may be decided taking into account two work
      queues: <span class="emphasis"><em>(i)</em></span> the
      <span class="emphasis"><em>certification</em></span> queue;
      <span class="emphasis"><em>(ii)</em></span> and on the binary log
      <span class="emphasis"><em>applier</em></span> queue. Whenever the size of one of
      these queues exceeds the user-defined threshold, the throttling
      mechanism is triggered. Only configure: <span class="emphasis"><em>(i)</em></span>
      whether to do flow control at the certifier or at the applier
      level, or both; and <span class="emphasis"><em>(ii)</em></span> what is the
      threshold for each queue.
    </p><p>
      The flow control depends on two basic mechanisms:
</p>
<div class="orderedlist">
<ol class="orderedlist" type="1"><li class="listitem"><p>
          the monitoring of members to collect some statistics on
          throughput and queue sizes of all group members to make
          educated guesses on what is the maximum write pressure each
          member should be subjected to;
        </p></li><li class="listitem"><p>
          the throttling of members that are trying to write beyond
          their fair-share of the available capacity at each moment in
          time.
</p></li></ol>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="group-replication-probes-and-statistics"></a>18.6.2.1 Probes and Statistics</h4>

</div>

</div>

</div>
<a class="indexterm" name="idm46444258657872"></a><p>
        The monitoring mechanism works by having each member deploying a
        set of probes to collect information about its work queues and
        throughput. It then propagates that information to the group
        periodically to share that data with the other members.
      </p><p>
        Such probes are scattered throughout the plugin stack and allow
        one to establish metrics, such as:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            the certifier queue size;
          </p></li><li class="listitem"><p>
            the replication applier queue size;
          </p></li><li class="listitem"><p>
            the total number of transactions certified;
          </p></li><li class="listitem"><p>
            the total number of remote transactions applied in the
            member;
          </p></li><li class="listitem"><p>
            the total number of local transactions.
</p></li></ul>
</div>
<p>
        Once a member receives a message with statistics from another
        member, it calculates additional metrics regarding how many
        transactions were certified, applied and locally executed in the
        last monitoring period.
      </p><p>
        Monitoring data is shared with others in the group periodically.
        The monitoring period must be high enough to allow the other
        members to decide on the current write requests, but low enough
        that it has minimal impact on group bandwidth. The information
        is shared every second, and this period is sufficient to address
        both concerns.
</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="group-replication-throttling"></a>18.6.2.2 Group Replication Throttling</h4>

</div>

</div>

</div>
<a class="indexterm" name="idm46444258647872"></a><p>
        Based on the metrics gathered across all servers in the group, a
        throttling mechanism kicks in and decides whether to limit the
        rate a member is able to execute/commit new transactions.
      </p><p>
        Therefore, metrics acquired from all members are the basis for
        calculating the capacity of each member: if a member has a large
        queue (for certification or the applier thread), then the
        capacity to execute new transactions should be close to ones
        certified or applied in the last period.
      </p><p>
        The lowest capacity of all the members in the group determines
        the real capacity of the group, while the number of local
        transactions determines how many members are writing to it, and,
        consequently, how many members should that available capacity be
        shared with.
      </p><p>
        This means that every member has an established write quota
        based on the available capacity, in other words a number of
        transactions it can safely issue for the next period. The
        writer-quota will be enforced by the throttling mechanism if the
        queue size of the certifier or the binary log applier exceeds a
        user-defined threshold.

        
      </p><p>
        The quota is reduced by the number of transactions that were
        delayed in the last period, and then also further reduced by 10%
        to allow the queue that triggered the problem to reduce its
        size. In order to avoid large jumps in throughput once the queue
        size goes beyond the threshold, the throughput is only allowed
        to grow by the same 10% per period after that.
      </p><p>
        The current throttling mechanism does not penalize transactions
        below quota, but delays finishing those transactions that exceed
        it until the end of the monitoring period. As a consequence, if
        the quota is very small for the write requests issued some
        transactions may have latencies close to the monitoring period.
</p>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="group-replication-message-compression"></a>18.6.3 Message Compression</h3>

</div>

</div>

</div>
<a class="indexterm" name="idm46444258639824"></a><p>
      For messages sent between online group members, Group Replication
      enables message compression by default. Whether a specific message
      is compressed depends on the threshold that you configure using
      the
      <a class="link" href="group-replication.html#sysvar_group_replication_compression_threshold"><code class="literal">group_replication_compression_threshold</code></a>
      system variable. Messages that have a payload larger than the
      specified number of bytes are compressed.
    </p><p>
      The default compression threshold is 1000000 bytes. You could use
      the following statements to increase the compression threshold to
      2MB, for example:
    </p><pre data-lang="sql" class="programlisting">STOP GROUP_REPLICATION;
SET GLOBAL group_replication_compression_threshold = 2097152;
START GROUP_REPLICATION;</pre><p>
      If you set
      <a class="link" href="group-replication.html#sysvar_group_replication_compression_threshold"><code class="literal">group_replication_compression_threshold</code></a>
      to zero, message compression is disabled.
    </p><p>
      Group Replication uses the LZ4 compression algorithm to compress
      messages sent in the group. Note that the maximum supported input
      size for the LZ4 compression algorithm is 2113929216 bytes. This
      limit is lower than the maximum possible value for the
      <a class="link" href="group-replication.html#sysvar_group_replication_compression_threshold"><code class="literal">group_replication_compression_threshold</code></a>
      system variable, which is matched to the maximum message size
      accepted by XCom. The LZ4 maximum input size is therefore a
      practical limit for message compression, and transactions above
      this size cannot be committed when message compression is enabled.
      With the LZ4 compression algorithm, do not set a value greater
      than 2113929216 bytes for
      <a class="link" href="group-replication.html#sysvar_group_replication_compression_threshold"><code class="literal">group_replication_compression_threshold</code></a>.
    </p><p>
      The value of
      <a class="link" href="group-replication.html#sysvar_group_replication_compression_threshold"><code class="literal">group_replication_compression_threshold</code></a>
      is not required by Group Replication to be the same on all group
      members. However, it is advisable to set the same value on all
      group members in order to avoid unnecessary rollback of
      transactions, failure of message delivery, or failure of message
      recovery.
    </p><p>
      From MySQL 8.0.18, you can also configure compression for messages
      sent for distributed recovery by the method of state transfer from
      a donor's binary log. Compression for these messages, which are
      sent from a donor already in the group to a joining member, is
      controlled separately using the
      <a class="link" href="group-replication.html#sysvar_group_replication_recovery_compression_algorithm"><code class="literal">group_replication_recovery_compression_algorithm</code></a>
      and
      <a class="link" href="group-replication.html#sysvar_group_replication_recovery_zstd_compression_level"><code class="literal">group_replication_recovery_zstd_compression_level</code></a>
      system variables. For more information, see
      <a class="xref" href="programs.html#connection-compression-control" title="4.2.6 Connection Compression Control">Section 4.2.6, “Connection Compression Control”</a>.
    </p><p>
      Binary log transaction compression (available as of MySQL 8.0.20),
      which is activated by the
      <a class="link" href="replication.html#sysvar_binlog_transaction_compression"><code class="literal">binlog_transaction_compression</code></a>
      system variable, can also be used to save bandwidth. The
      transaction payloads remain compressed when they are transferred
      between group members. If you use binary log transaction
      compression in combination with Group Replication's message
      compression, message compression has less opportunity to act on
      the data, but can still compress headers and those events and
      transaction payloads that are uncompressed. For more information
      on binary log transaction compression, see
      <a class="xref" href="server-administration.html#binary-log-transaction-compression" title="5.4.4.5 Binary Log Transaction Compression">Section 5.4.4.5, “Binary Log Transaction Compression”</a>.
    </p><p>
      Compression for messages sent in the group happens at the group
      communication engine level, before the data is handed over to the
      group communication thread, so it takes place within the context
      of the <code class="literal">mysql</code> user session thread. If the
      message payload size exceeds the threshold set by
      <a class="link" href="group-replication.html#sysvar_group_replication_compression_threshold"><code class="literal">group_replication_compression_threshold</code></a>,
      the transaction payload is compressed before being sent out to the
      group, and decompressed when it is received. Upon receiving a
      message, the member checks the message envelope to verify whether
      it is compressed or not. If needed, then the member decompresses
      the transaction, before delivering it to the upper layer. This
      process is shown in the following figure.
</p>
<div class="figure">
<a name="idm46444258616880"></a><p class="title"><b>Figure 18.15 Compression Support</b></p>
<div class="figure-contents">

<div class="mediaobject">
<img src="images/gr-compress-decompress.png" width="603" height="492" alt="The MySQL Group Replication plugin architecture is shown as described in an earlier topic, with the five layers of the plugin positioned between the MySQL server and the replication group. Compression and decompression are handled by the Group Communication System API, which is the fourth layer of the Group Replication plugin. The group communication engine (the fifth layer of the plugin) and the group members use the compressed transactions with the smaller data size. The MySQL Server core and the three higher layers of the Group Replication plugin (the APIs, the capture, applier, and recovery components, and the replication protocol module) use the original transactions with the larger data size.">
</div>

</div>

</div>
<br class="figure-break"><p>
      When network bandwidth is a bottleneck, message compression can
      provide up to 30-40% throughput improvement at the group
      communication level. This is especially important within the
      context of large groups of servers under load. The TCP
      peer-to-peer nature of the interconnections between
      <span class="emphasis"><em>N</em></span> participants in the group makes the sender
      send the same amount of data <span class="emphasis"><em>N</em></span> times.
      Furthermore, binary logs are likely to exhibit a high compression
      ratio. This makes compression a compelling feature for Group
      Replication workloads that contain large transactions.
</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="group-replication-performance-message-fragmentation"></a>18.6.4 Message Fragmentation</h3>

</div>

</div>

</div>
<a class="indexterm" name="idm46444258606864"></a><p>
      When an abnormally large message is sent between Group Replication
      group members, it can result in some group members being reported
      as failed and expelled from the group. This is because the single
      thread used by Group Replication's group communication engine
      (XCom, a Paxos variant) is occupied processing the message for too
      long, so some of the group members might report the receiver as
      failed. From MySQL 8.0.16, by default, large messages are
      automatically split into fragments that are sent separately and
      reassembled by the recipients.
    </p><p>
      The system variable
      <a class="link" href="group-replication.html#sysvar_group_replication_communication_max_message_size"><code class="literal">group_replication_communication_max_message_size</code></a>
      specifies a maximum message size for Group Replication
      communications, above which messages are fragmented. The default
      maximum message size is 10485760 bytes (10 MiB). The greatest
      permitted value is the same as the maximum value of the
      <a class="link" href="replication.html#sysvar_slave_max_allowed_packet"><code class="literal">slave_max_allowed_packet</code></a> system
      variable, which is 1073741824 bytes (1 GB). The setting for
      <a class="link" href="group-replication.html#sysvar_group_replication_communication_max_message_size"><code class="literal">group_replication_communication_max_message_size</code></a>
      must be less than the
      <a class="link" href="replication.html#sysvar_slave_max_allowed_packet"><code class="literal">slave_max_allowed_packet</code></a> setting,
      because the applier thread cannot handle message fragments larger
      than <a class="link" href="replication.html#sysvar_slave_max_allowed_packet"><code class="literal">slave_max_allowed_packet</code></a>. To
      switch off fragmentation, specify a zero value for
      <a class="link" href="group-replication.html#sysvar_group_replication_communication_max_message_size"><code class="literal">group_replication_communication_max_message_size</code></a>.
    </p><p>
      As with most other Group Replication system variables, you must
      restart the Group Replication plugin for the change to take
      effect. For example:
    </p><pre data-lang="sql" class="programlisting">STOP GROUP_REPLICATION;
SET GLOBAL group_replication_communication_max_message_size= 5242880;
START GROUP_REPLICATION;</pre><p>
      Message delivery for a fragmented message is considered complete
      when all the fragments of the message have been received and
      reassembled by all the group members. Fragmented messages include
      information in their headers that enables a member joining during
      message transmission to recover the earlier fragments that were
      sent before it joined. If the joining member fails to recover the
      fragments, it expels itself from the group.
    </p><p>
      In order for a replication group to use fragmentation, all group
      members must be at MySQL 8.0.16 or above, and the Group
      Replication communication protocol version in use by the group
      must allow fragmentation. You can inspect the communication
      protocol in use by a group by using the
      <a class="link" href="sql-statements.html#udf_group-replication-get-communication-protocol"><code class="literal">group_replication_get_communication_protocol()</code></a>
      UDF, which returns the oldest MySQL Server version that the group
      supports. Versions from MySQL 5.7.14 allow compression of
      messages, and versions from MySQL 8.0.16 also allow fragmentation
      of messages. If all group members are at MySQL 8.0.16 or above and
      there is no requirement to allow members at earlier releases to
      join, you can use the
      <a class="link" href="sql-statements.html#udf_group-replication-set-communication-protocol"><code class="literal">group_replication_set_communication_protocol()</code></a>
      UDF to set the communication protocol version to MySQL 8.0.16 or
      above in order to allow fragmentation. For more information, see
      <a class="xref" href="group-replication.html#group-replication-communication-protocol" title="18.4.1.4 Setting a Group's Communication Protocol Version">Section 18.4.1.4, “Setting a Group's Communication Protocol Version”</a>.
    </p><p>
      If a replication group cannot use fragmentation because some
      members do not support it, the system variable
      <a class="link" href="group-replication.html#sysvar_group_replication_transaction_size_limit"><code class="literal">group_replication_transaction_size_limit</code></a>
      can be used to limit the maximum size of transactions the group
      accepts. In MySQL 8.0, the default setting is approximately 143
      MB. Transactions above this size are rolled back. You can also use
      the system variable
      <a class="link" href="group-replication.html#sysvar_group_replication_member_expel_timeout"><code class="literal">group_replication_member_expel_timeout</code></a>
      to allow additional time (up to an hour) before a member under
      suspicion of having failed is expelled from the group.
</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="group-replication-performance-xcom-cache"></a>18.6.5 XCom Cache Management</h3>

</div>

</div>

</div>
<a class="indexterm" name="idm46444258583760"></a><p>
      The group communication engine for Group Replication (XCom, a
      Paxos variant) includes a cache for messages (and their metadata)
      exchanged between the group members as a part of the consensus
      protocol. Among other functions, the message cache is used for
      recovery by members that return to the group after a period where
      they were unable to communicate with the other group members.
    </p><p>
      From MySQL 8.0.16, a cache size limit can be set for XCom's
      message cache using the
      <a class="link" href="group-replication.html#sysvar_group_replication_message_cache_size"><code class="literal">group_replication_message_cache_size</code></a>
      system variable. This system variable has a default and minimum
      setting of 1 GB, which is the size of the message cache in MySQL
      Server versions prior to MySQL 8.0.16. If the cache size limit is
      reached, XCom removes the oldest entries that have been decided
      and delivered. Ensure that sufficient memory is available on your
      system for your chosen cache size limit, considering the size of
      MySQL Server's other caches and object pools.
    </p><p>
      If an unreachable member that is attempting to reconnect requires
      a message for recovery, but the message has already been removed
      from the message cache, the member cannot reconnect. This
      situation is more likely to occur if you have used the
      <a class="link" href="group-replication.html#sysvar_group_replication_member_expel_timeout"><code class="literal">group_replication_member_expel_timeout</code></a>
      system variable (introduced in MySQL 8.0.13) to specify an
      additional delay time before suspect members are expelled from a
      group. Group Replication's Group Communication System (GCS) alerts
      you, by a warning message, when a message that is likely to be
      needed for recovery by a member that is currently unreachable is
      removed from the message cache. This warning message is logged on
      all the active group members (only once for each unreachable
      member). Although the group members cannot know for sure what
      message was the last message seen by the unreachable member, the
      warning message indicates that the cache size might not be
      sufficient to support your chosen waiting period before a member
      is expelled. In this situation, consider increasing the cache size
      limit with reference to the expected volume of messages in the
      time period specified by the
      <a class="link" href="group-replication.html#sysvar_group_replication_member_expel_timeout"><code class="literal">group_replication_member_expel_timeout</code></a>
      system variable, so that the cache contains all the missed
      messages required for members to return successfully. You can also
      consider increasing the cache size limit temporarily if you expect
      a member to become unreachable for an unusual period of time.
    </p><p>
      If you are considering reducing the cache size limit, you can
      query the Performance Schema table
      <a class="link" href="performance-schema.html#memory-summary-tables" title="26.12.18.10 Memory Summary Tables"><code class="literal">memory_summary_global_by_event_name</code></a>
      using the following statement:
    </p><pre data-lang="sql" class="programlisting">SELECT * FROM performance_schema.memory_summary_global_by_event_name
  WHERE EVENT_NAME LIKE 'memory/group_rpl/GCS_XCom::xcom_cache';</pre><p>
      This returns memory usage statistics for the message cache,
      including the current number of cached entries and current size of
      the cache. If you reduce the cache size limit, XCom removes the
      oldest entries that have been decided and delivered until the
      current size is below the limit. XCom might temporarily exceed the
      cache size limit while this removal process is ongoing.
</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="group-replication-responses-failure"></a>18.6.6 Responses to Failure Detection and Network Partitioning</h3>

</div>

</div>

</div>
<div class="toc">
<dl class="toc"><dt><span class="section"><a href="group-replication.html#group-replication-responses-failure-expel">18.6.6.1 Expel Timeout</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-responses-failure-partition">18.6.6.2 Unreachable Majority Timeout</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-responses-failure-rejoin">18.6.6.3 Auto-Rejoin</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-responses-failure-exit">18.6.6.4 Exit Action</a></span></dt></dl>
</div>
<a class="indexterm" name="idm46444258570304"></a><a class="indexterm" name="idm46444258568848"></a><a class="indexterm" name="idm46444258567360"></a><p>
      Group Replication's failure detection mechanism is designed to
      identify group members that are no longer communicating with the
      group, and expel them as and when it seems likely that they have
      failed. Having a failure detection mechanism increases the chance
      that the group contains a majority of correctly working members,
      and that requests from clients are therefore processed correctly.
    </p><p>
      Normally, all group members regularly exchange messages with all
      other group members. If a group member does not receive any
      messages from a particular fellow member for 5 seconds, when this
      detection period ends, it creates a suspicion of the fellow
      member. When a suspicion times out, the suspected member is
      assumed to have failed, and is expelled from the group. An
      expelled member is removed from the membership list seen by the
      other members, but it does not know that it has been expelled from
      the group, so it sees itself as online and the other members as
      unreachable. If the member has not in fact failed (for example,
      because it was just disconnected due to a temporary network issue)
      and it is able to resume communication with the other members, it
      receives a view containing the information that it has been
      expelled from the group.
    </p><p>
      The responses of group members, including the failed member
      itself, to these situations can be configured at a number of
      points in the process. By default, the following behaviors happen
      if a member is suspected of having failed:
</p>
<div class="orderedlist">
<ol class="orderedlist" type="1"><li class="listitem"><p>
          When a suspicion is created, it times out immediately (its
          lifetime is set to 0), so the suspected member is expelled as
          soon as the expired suspicion is identified. The member could
          potentially survive for a further few seconds after the
          timeout because the check for expired suspicions is carried
          out periodically.
        </p></li><li class="listitem"><p>
          If an expelled member resumes communication and realises that
          it was expelled, it does not try to rejoin the group and
          accepts its expulsion.
        </p></li><li class="listitem"><p>
          When an expelled member accepts its expulsion, it switches to
          super read only mode and awaits operator attention. (The
          exception is in releases from MySQL 8.0.12 to 8.0.15, where
          the default was for the member to shut itself down. From MySQL
          8.0.16, the behavior was changed to match the behavior in
          MySQL 5.7.)
</p></li></ol>
</div>
<p>
      These defaults are set to prioritize the correct operation of the
      group and the correct handling of requests. However, they might be
      inconvenient in the case of slower networks or networks with a
      high rate of transient failures, because in these situations there
      could be a frequent requirement for operator intervention to fix
      expelled members. They also do not allow for continued operation
      of the group to be planned in the case of expected network
      failures or machine slowdowns. You can use the Group Replication
      configuration options described in this section to change these
      behaviors either permanently or temporarily, to suit your system's
      requirements and your priorities.
    </p><p>
      Members that have not failed might lose contact with part, but not
      all, of the replication group due to a network partition. For
      example, in a group of 5 servers (S1,S2,S3,S4,S5), if there is a
      disconnection between (S1,S2) and (S3,S4,S5) there is a network
      partition. The first group (S1,S2) is now in a minority because it
      cannot contact more than half of the group. Any transactions that
      are processed by the members in the minority group are blocked,
      because the majority of the group is unreachable, therefore the
      group cannot achieve quorum. For a detailed description of this
      scenario, see
      <a class="xref" href="group-replication.html#group-replication-network-partitioning" title="18.4.4 Network Partitioning">Section 18.4.4, “Network Partitioning”</a>. In this
      situation, the default behavior is for the members in both the
      minority and the majority to remain in the group, continue to
      accept transactions (although they are blocked on the members in
      the minority), and wait for operator intervention. This behavior
      is also configurable.
    </p><p>
      Note that where group members are at an older MySQL Server release
      that does not support a relevant setting, or at a release with a
      different default, they act towards themselves and other group
      members according to the default behaviors stated above. For
      example, a member that does not support the
      <a class="link" href="group-replication.html#sysvar_group_replication_member_expel_timeout"><code class="literal">group_replication_member_expel_timeout</code></a>
      system variable expels other members as soon as an expired
      suspicion is detected, and this expulsion is accepted by other
      members even if they support the system variable and have a longer
      timeout set.
</p>
<div class="section">

<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="group-replication-responses-failure-expel"></a>18.6.6.1 Expel Timeout</h4>
</div>
</div>
</div>
<p>
        You can use the
        <a class="link" href="group-replication.html#sysvar_group_replication_member_expel_timeout"><code class="literal">group_replication_member_expel_timeout</code></a>
        system variable, which is available from MySQL 8.0.13, to allow
        additional time between the creation of a suspicion and the
        expulsion of the suspect member.
      </p><p>
        A group member is expelled when another member's suspicion of it
        (or its own suspicion of itself) times out. By default,
        <a class="link" href="group-replication.html#sysvar_group_replication_member_expel_timeout"><code class="literal">group_replication_member_expel_timeout</code></a>
        is set to 0, meaning that there is no waiting period and a
        suspected member is liable for expulsion immediately after the
        5-second detection period ends. An additional short period of
        time might elapse before the expelling mechanism detects and
        implements the expulsion. If a group member is at an older MySQL
        Server version that does not support this setting, this is its
        behavior towards other members or itself.
      </p><p>
        To avoid unnecessary expulsions on slower networks, or in the
        case of expected transient network failures or machine
        slowdowns, you can specify a timeout value greater than zero, up
        to a maximum of 3600 seconds (1 hour). Suspect members in this
        state are listed as <code class="literal">UNREACHABLE</code>, but are not
        removed from the group's membership list. If a suspect member
        becomes active again before the suspicion times out, it rejoins
        the group, applies all the messages that were buffered by the
        remaining group members, and enters <code class="literal">ONLINE</code>
        state.
      </p><p>
        If the timeout is exceeded, the suspect member is liable for
        expulsion immediately after the suspicion times out. If the
        member is able to resume communications and receives a view
        where it is expelled, it realises it was expelled. By default,
        the expelled member then follows the exit action specified by
        <a class="link" href="group-replication.html#sysvar_group_replication_exit_state_action"><code class="literal">group_replication_exit_state_action</code></a>.
        Alternatively you can use the
        <a class="link" href="group-replication.html#sysvar_group_replication_autorejoin_tries"><code class="literal">group_replication_autorejoin_tries</code></a>
        system variable, which is available from MySQL 8.0.16, to make
        the member automatically try to rejoin the group.
      </p><p>
        The waiting period before expelling a member only applies to
        members that have previously been active in the group.
        Non-members that were never active in the group do not get this
        waiting period and are removed after the initial detection
        period because they took too long to join.
      </p><p>
        If any members in a group are currently under suspicion, the
        group membership cannot be reconfigured (by adding or removing
        members or electing a new leader). If group membership changes
        need to be implemented while one or more members are under
        suspicion, and you want the suspect members to remain in the
        group, take any actions required to make the members active
        again, if that is possible. If you cannot make the members
        active again and you want them to be expelled from the group,
        you can force the suspicions to time out immediately. Do this by
        changing the value of
        <a class="link" href="group-replication.html#sysvar_group_replication_member_expel_timeout"><code class="literal">group_replication_member_expel_timeout</code></a>
        on any active members to a value lower than the time that has
        already elapsed since the suspicions were created. The suspect
        members then become liable for expulsion immediately.
      </p><p>
        If a replication group member stops unexpectedly and is
        immediately restarted (for example, because it was started with
        <code class="literal">mysqld_safe</code>), it automatically attempts to
        rejoin the group if
        <a class="link" href="group-replication.html#sysvar_group_replication_start_on_boot"><code class="literal">group_replication_start_on_boot=on</code></a>
        is set. In this situation, it is possible for the restart and
        rejoin attempt to take place before the member's previous
        incarnation has been expelled from the group, in which case the
        member cannot rejoin. From MySQL 8.0.19, Group Replication
        automatically uses a Group Communication System (GCS) feature to
        retry the rejoin attempt for the member 10 times, with a
        5-second interval between each retry. This should cover most
        cases and allow enough time for the previous incarnation to be
        expelled from the group, letting the member rejoin. Note that if
        the
        <a class="link" href="group-replication.html#sysvar_group_replication_member_expel_timeout"><code class="literal">group_replication_member_expel_timeout</code></a>
        system variable is set to specify a longer waiting period before
        the member is expelled, the automatic rejoin attempts might
        still not succeed.
      </p><p>
        For alternative mitigation strategies to avoid unnecessary
        expulsions where the
        <a class="link" href="group-replication.html#sysvar_group_replication_member_expel_timeout"><code class="literal">group_replication_member_expel_timeout</code></a>
        system variable is not available, see
        <a class="xref" href="group-replication.html#group-replication-limitations" title="18.9.2 Group Replication Limitations">Section 18.9.2, “Group Replication Limitations”</a>.
</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="group-replication-responses-failure-partition"></a>18.6.6.2 Unreachable Majority Timeout</h4>

</div>

</div>

</div>
<p>
        By default, members that find themselves in a minority due to a
        network partition do not automatically leave the group. You can
        use the system variable
        <a class="link" href="group-replication.html#sysvar_group_replication_unreachable_majority_timeout"><code class="literal">group_replication_unreachable_majority_timeout</code></a>
        to set a number of seconds for a member to wait after losing
        contact with the majority of group members, and then exit the
        group. Setting a timeout means you do not need to pro-actively
        monitor for servers that are in a minority group after a network
        partition, and you can avoid the possibility of creating a
        split-brain situation (with two versions of the group
        membership) due to inappropriate intervention.
      </p><p>
        When the timeout specified by
        <a class="link" href="group-replication.html#sysvar_group_replication_unreachable_majority_timeout"><code class="literal">group_replication_unreachable_majority_timeout</code></a>
        elapses, all pending transactions that have been processed by
        the member and the others in the minority group are rolled back,
        and the servers in that group move to the
        <code class="literal">ERROR</code> state. By default, a minority member
        then follows the exit action specified by
        <a class="link" href="group-replication.html#sysvar_group_replication_exit_state_action"><code class="literal">group_replication_exit_state_action</code></a>.
        Alternatively you can use the
        <a class="link" href="group-replication.html#sysvar_group_replication_autorejoin_tries"><code class="literal">group_replication_autorejoin_tries</code></a>
        system variable, which is available from MySQL 8.0.16, to make
        the member automatically try to rejoin the group.
      </p><p>
        Consider the following points when deciding whether or not to
        set an unreachable majority timeout:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            In a symmetric group, for example a group with two or four
            servers, if both partitions contain an equal number of
            servers, both groups consider themselves to be in a minority
            and enter the <code class="literal">ERROR</code> state. In this
            situation, the group has no functional partition.
          </p></li><li class="listitem"><p>
            While a minority group exists, any transactions processed by
            the minority group are accepted, but blocked because the
            minority servers cannot reach quorum, until either
            <a class="link" href="sql-statements.html#stop-group-replication" title="13.4.3.2 STOP GROUP_REPLICATION Statement"><code class="literal">STOP GROUP_REPLICATION</code></a> is
            issued on those servers or the unreachable majority timeout
            is reached.
          </p></li><li class="listitem"><p>
            If you do not set an unreachable majority timeout, the
            servers in the minority group will never enter the
            <code class="literal">ERROR</code> state automatically, and you must
            stop them manually.
          </p></li><li class="listitem"><p>
            Setting an unreachable majority timeout has no effect if it
            is set on the servers in the minority group after the loss
            of majority has been detected.
</p></li></ul>
</div>
<p>
        If you do not use the
        <a class="link" href="group-replication.html#sysvar_group_replication_unreachable_majority_timeout"><code class="literal">group_replication_unreachable_majority_timeout</code></a>system
        variable, the process for operator invention in the event of a
        network partition is described in
        <a class="xref" href="group-replication.html#group-replication-network-partitioning" title="18.4.4 Network Partitioning">Section 18.4.4, “Network Partitioning”</a>. The
        process involves checking which servers are functioning and
        forcing a new group membership if necessary.
</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="group-replication-responses-failure-rejoin"></a>18.6.6.3 Auto-Rejoin</h4>

</div>

</div>

</div>
<p>
        The
        <a class="link" href="group-replication.html#sysvar_group_replication_autorejoin_tries"><code class="literal">group_replication_autorejoin_tries</code></a>
        system variable, which is available from MySQL 8.0.16, makes a
        member that has been expelled or reached its unreachable
        majority timeout try to rejoin the group automatically. You can
        specify a number of attempts that the member makes to rejoin the
        group, instead of just accepting its expulsion as soon as it
        resumes communication. Activate auto-rejoin if you can tolerate
        the possibility of stale reads and want to minimize the need for
        manual intervention, especially where transient network issues
        fairly often result in the expulsion of members.
      </p><p>
        When the member's expulsion or unreachable majority timeout is
        reached, it makes an attempt to rejoin (using the current plugin
        option values), then continues to make further auto-rejoin
        attempts up to the specified number of tries. After an
        unsuccessful auto-rejoin attempt, the member waits 5 minutes
        before the next try. If the specified number of tries is
        exhausted without the member rejoining or being stopped, the
        member proceeds to the action specified by the
        <a class="link" href="group-replication.html#sysvar_group_replication_exit_state_action"><code class="literal">group_replication_exit_state_action</code></a>
        system variable.
      </p><p>
        During the auto-rejoin procedure, the expelled member remains in
        super read only mode and displays an <code class="literal">ERROR</code>
        state on its view of the replication group. Bear in mind that
        while a member remains in super read only mode, although writes
        cannot be made on the member, reads can, with an increasing
        likelihood of stale reads over time. If you do want to intervene
        to take the member offline, the member can be stopped manually
        at any time by using a <a class="link" href="sql-statements.html#stop-group-replication" title="13.4.3.2 STOP GROUP_REPLICATION Statement"><code class="literal">STOP
        GROUP_REPLICATION</code></a> statement or shutting down the
        server.
      </p><p>
        You can monitor the auto-rejoin procedure using the Performance
        Schema. While an auto-rejoin procedure is taking place, the
        Performance Schema table
        <a class="link" href="performance-schema.html#events-stages-current-table" title="26.12.5.1 The events_stages_current Table"><code class="literal">events_stages_current</code></a> shows the
        event <span class="quote">“<span class="quote">Undergoing auto-rejoin procedure</span>”</span>, with the
        number of retries that have been attempted so far during this
        instance of the procedure (in the
        <code class="literal">WORK_COMPLETED</code> field). The
        <a class="link" href="performance-schema.html#stage-summary-tables" title="26.12.18.2 Stage Summary Tables"><code class="literal">events_stages_summary_global_by_event_name</code></a>
        table shows the number of times the server instance has
        initiated the auto-rejoin procedure (in the
        <code class="literal">COUNT_STAR</code> field). The
        <a class="link" href="performance-schema.html#events-stages-history-long-table" title="26.12.5.3 The events_stages_history_long Table"><code class="literal">events_stages_history_long</code></a> table
        shows the time each of these auto-rejoin procedures was
        completed (in the <code class="literal">TIMER_END</code> field).
</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="group-replication-responses-failure-exit"></a>18.6.6.4 Exit Action</h4>

</div>

</div>

</div>
<p>
        The
        <a class="link" href="group-replication.html#sysvar_group_replication_exit_state_action"><code class="literal">group_replication_exit_state_action</code></a>
        system variable, which is available from MySQL 8.0.12 and MySQL
        5.7.24, specifies what Group Replication does when the member
        leaves the group unintentionally due to an error or problem, and
        either fails to auto-rejoin or does not try. Note that in the
        case of an expelled member, the member does not know that it was
        expelled until it reconnects to the group, so the specified
        action is only taken if the member manages to reconnect, or if
        the member raises a suspicion on itself and expels itself.
      </p><p>
        In order of impact, the exit actions are as follows:
</p>
<div class="orderedlist">
<ol class="orderedlist" type="1"><li class="listitem"><p>
            If <code class="literal">READ_ONLY</code> is the exit action, the
            instance switches MySQL to super read only mode by setting
            the system variable
            <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only</code></a> to
            <code class="literal">ON</code>. When the member is in super read only
            mode, clients cannot make any updates, even if they have the
            <a class="link" href="security.html#priv_connection-admin"><code class="literal">CONNECTION_ADMIN</code></a> privilege
            (or the deprecated <a class="link" href="security.html#priv_super"><code class="literal">SUPER</code></a>
            privilege). However, clients can still read data, and
            because updates are no longer being made, there is a
            probability of stale reads which increases over time. With
            this setting, you therefore need to pro-actively monitor the
            servers for failures. This exit action is the default from
            MySQL 8.0.15. After this exit action is taken, the member's
            status is displayed as <code class="literal">ERROR</code> in the view
            of the group.
          </p></li><li class="listitem"><p>
            If <code class="literal">OFFLINE_MODE</code> is the exit action, the
            instance switches MySQL to offline mode by setting the
            system variable
            <a class="link" href="server-administration.html#sysvar_offline_mode"><code class="literal">offline_mode</code></a> to
            <code class="literal">ON</code>. When the member is in offline mode,
            connected client users are disconnected on their next
            request and connections are no longer accepted, with the
            exception of client users that have the
            <a class="link" href="security.html#priv_connection-admin"><code class="literal">CONNECTION_ADMIN</code></a> privilege
            (or the deprecated <a class="link" href="security.html#priv_super"><code class="literal">SUPER</code></a>
            privilege). Group Replication also sets the system variable
            <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only</code></a> to
            <code class="literal">ON</code>, so clients cannot make any updates,
            even if they have connected with the
            <a class="link" href="security.html#priv_connection-admin"><code class="literal">CONNECTION_ADMIN</code></a> or
            <a class="link" href="security.html#priv_super"><code class="literal">SUPER</code></a> privilege. This exit
            action prevents both updates and stale reads (with the
            exception of reads by client users with the stated
            privileges), and enables proxy tools such as MySQL Router to
            recognize that the server is unavailable and redirect client
            connections. It also leaves the instance running so that an
            administrator can attempt to resolve the issue without
            shutting down MySQL. This exit action is available from
            MySQL 8.0.18. After this exit action is taken, the member's
            status is displayed as <code class="literal">ERROR</code> in the view
            of the group (not <code class="literal">OFFLINE</code>, which means a
            member has Group Replication functionality available but
            does not currently belong to a group).
          </p></li><li class="listitem"><p>
            If <code class="literal">ABORT_SERVER</code> is the exit action, the
            instance shuts down MySQL. Instructing the member to shut
            itself down prevents all stale reads and client updates, but
            it means that the MySQL Server instance is unavailable and
            must be restarted, even if the issue could have been
            resolved without that step. This exit action was the default
            from MySQL 8.0.12, when the system variable was added, to
            MySQL 8.0.15 inclusive. After this exit action is taken, the
            member is removed from the listing of servers in the view of
            the group.
</p></li></ol>
</div>
<p>
        Bear in mind that operator intervention is required whatever
        exit action is set, as an ex-member that has exhausted its
        auto-rejoin attempts (or never had any) and has been expelled
        from the group is not allowed to rejoin without a restart of
        Group Replication. The exit action only influences whether or
        not clients can still read data on the server that was unable to
        rejoin the group, and whether or not the server stays running.
</p>
<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Important
</div>
<p>
          If a failure occurs before the member has successfully joined
          the group, the exit action specified by
          <a class="link" href="group-replication.html#sysvar_group_replication_exit_state_action"><code class="literal">group_replication_exit_state_action</code></a>
          <span class="emphasis"><em>is not taken</em></span>. This is the case if there
          is a failure during the local configuration check, or a
          mismatch between the configuration of the joining member and
          the configuration of the group. In these situations, the
          <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only</code></a> system
          variable is left with its original value, and the server does
          not shut down MySQL. To ensure that the server cannot accept
          updates when Group Replication did not start, we therefore
          recommend that
          <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only=ON</code></a> is set in
          the server's configuration file at startup, which Group
          Replication will change to <code class="literal">OFF</code> on primary
          members after it has been started successfully. This safeguard
          is particularly important when the server is configured to
          start Group Replication on server boot
          (<a class="link" href="group-replication.html#sysvar_group_replication_start_on_boot"><code class="literal">group_replication_start_on_boot=ON</code></a>),
          but it is also useful when Group Replication is started
          manually using a <a class="link" href="sql-statements.html#start-group-replication" title="13.4.3.1 START GROUP_REPLICATION Statement"><code class="literal">START
          GROUP_REPLICATION</code></a> command.
</p>
</div>
<p>
        If a failure occurs after the member has successfully joined the
        group, the specified exit action is taken. This is the case in
        the following situations:
</p>
<div class="orderedlist">
<ol class="orderedlist" type="1"><li class="listitem"><p>
            <span class="emphasis"><em>Applier error</em></span> - There is an error in
            the replication applier. This issue is not recoverable.
          </p></li><li class="listitem"><p>
            <span class="emphasis"><em>Distributed recovery not possible</em></span> -
            There is an issue that means Group Replication's distributed
            recovery process (which uses remote cloning operations and
            state transfer from the binary log) cannot be completed.
            Group Replication retries distributed recovery automatically
            where this makes sense, but stops if there are no more
            options to complete the process. For details, see
            <a class="xref" href="group-replication.html#group-replication-distributed-recovery-fault" title="18.4.3.3 Fault Tolerance for Distributed Recovery">Section 18.4.3.3, “Fault Tolerance for Distributed Recovery”</a>.
          </p></li><li class="listitem"><p>
            <span class="emphasis"><em>Group configuration change error</em></span> - An
            error occurred during a group-wide configuration change
            carried out using a UDF, as described in
            <a class="xref" href="group-replication.html#group-replication-configuring-online-group" title="18.4.1 Configuring an Online Group">Section 18.4.1, “Configuring an Online Group”</a>.
          </p></li><li class="listitem"><p>
            <span class="emphasis"><em>Primary election error</em></span> - An error
            occurred during election of a new primary member for a group
            in single-primary mode, as described in
            <a class="xref" href="group-replication.html#group-replication-single-primary-mode" title="18.1.3.1 Single-Primary Mode">Section 18.1.3.1, “Single-Primary Mode”</a>.
          </p></li><li class="listitem"><p>
            <span class="emphasis"><em>Unreachable majority timeout</em></span> - The
            member has lost contact with a majority of the group members
            so is in a minority, and a timeout that was set by the
            <a class="link" href="group-replication.html#sysvar_group_replication_unreachable_majority_timeout"><code class="literal">group_replication_unreachable_majority_timeout</code></a>
            system variable has expired.
          </p></li><li class="listitem"><p>
            <span class="emphasis"><em>Member expelled from group</em></span> - A
            suspicion has been raised on the member, and any timeout set
            by the
            <a class="link" href="group-replication.html#sysvar_group_replication_member_expel_timeout"><code class="literal">group_replication_member_expel_timeout</code></a>
            system variable has expired, and the member has resumed
            communication with the group and found that it has been
            expelled.
          </p></li><li class="listitem"><p>
            <span class="emphasis"><em>Out of auto-rejoin attempts</em></span> - The
            <a class="link" href="group-replication.html#sysvar_group_replication_autorejoin_tries"><code class="literal">group_replication_autorejoin_tries</code></a>
            system variable was set to specify a number of auto-rejoin
            attempts after a loss of majority or expulsion, and the
            member completed this number of attempts without success.
</p></li></ol>
</div>
<p>
        The following table summarizes the failure scenarios and actions
        in each case:
</p>
<div class="table">
<a name="idm46444258439504"></a><p class="title"><b>Table 18.4 Exit actions in Group Replication failure situations</b></p>
<div class="table-contents">
<table frame="all" summary="Summarizes how the selected exit action does or does not operate depending on the failure situation"><col width="33%" align="left"><col width="33%" align="left"><col width="33%" align="left"><thead><tr>
            <th scope="col"><p>
                Failure situation
              </p></th>
            <th scope="col"><p>
                Group Replication started with <code class="literal">START
                GROUP_REPLICATION</code>
              </p></th>
            <th scope="col"><p>
                Group Replication started with
                <code class="literal">group_replication_start_on_boot =ON</code>
              </p></th>
          </tr></thead><tbody><tr>
            <td scope="row"><p>
                Member fails local configuration check
              </p><p>
                Mismatch between joining member and group configuration
              </p></td>
            <td><p>
                <code class="literal">super_read_only</code> and
                <code class="literal">offline_mode</code> unchanged
              </p><p>
                MySQL continues running
              </p><p>
                Set <code class="literal">super_read_only=ON</code> at startup to
                prevent updates
              </p></td>
            <td><p>
                <code class="literal">super_read_only</code> and
                <code class="literal">offline_mode</code> unchanged
              </p><p>
                MySQL continues running
              </p><p>
                Set <code class="literal">super_read_only=ON</code> at startup to
                prevent updates (Important)
              </p></td>
          </tr><tr>
            <td scope="row"><p>
                Applier error on member
              </p><p>
                Distributed recovery not possible
              </p><p>
                Group configuration change error
              </p><p>
                Primary election error
              </p><p>
                Unreachable majority timeout
              </p><p>
                Member expelled from group
              </p><p>
                Out of auto-rejoin attempts
              </p></td>
            <td><p>
                <code class="literal">super_read_only</code> set to
                <code class="literal">ON</code>
              </p><p>
                OR
              </p><p>
                <code class="literal">offline_mode</code> and
                <code class="literal">super_read_only</code> set to
                <code class="literal">ON</code>
              </p><p>
                OR
              </p><p>
                MySQL shuts down
              </p></td>
            <td><p>
                <code class="literal">super_read_only</code> set to
                <code class="literal">ON</code>
              </p><p>
                OR
              </p><p>
                <code class="literal">offline_mode</code> and
                <code class="literal">super_read_only</code> set to
                <code class="literal">ON</code>
              </p><p>
                OR
              </p><p>
                MySQL shuts down
              </p></td>
</tr></tbody></table>
</div>

</div>
<br class="table-break">
</div>

</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a name="group-replication-upgrade"></a>18.7 Upgrading Group Replication</h2>

</div>

</div>

</div>
<div class="toc">
<dl class="toc"><dt><span class="section"><a href="group-replication.html#group-replication-online-upgrade-combining-versions">18.7.1 Combining Different Member Versions in a Group</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-offline-upgrade">18.7.2 Group Replication Offline Upgrade</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-online-upgrade">18.7.3 Group Replication Online Upgrade</a></span></dt></dl>
</div>
<a class="indexterm" name="idm46444258402432"></a><p>
    This section explains how to upgrade a Group Replication setup. The
    basic process of upgrading members of a group is the same as
    upgrading stand-alone instances, see <a class="xref" href="installing.html#upgrading" title="2.11 Upgrading MySQL">Section 2.11, “Upgrading MySQL”</a> for
    the actual process of doing upgrade and types available. Choosing
    between an in-place or logical upgrade depends on the amount of data
    stored in the group. Usually an in-place upgrade is faster, and
    therefore is recommended. You should also consult
    <a class="xref" href="replication.html#replication-upgrade" title="17.5.3 Upgrading a Replication Setup">Section 17.5.3, “Upgrading a Replication Setup”</a>.
  </p><p>
    While you are in the process of upgrading an online group, in order
    to maximize availability, you might need to have members with
    different MySQL Server versions running at the same time. Group
    Replication includes compatibility policies that enable you to
    safely combine members running different versions of MySQL in the
    same group during the upgrade procedure. Depending on your group,
    the effects of these policies might affect the order in which you
    should upgrade group members. For details, see
    <a class="xref" href="group-replication.html#group-replication-online-upgrade-combining-versions" title="18.7.1 Combining Different Member Versions in a Group">Section 18.7.1, “Combining Different Member Versions in a Group”</a>.
  </p><p>
    If your group can be taken fully offline see
    <a class="xref" href="group-replication.html#group-replication-offline-upgrade" title="18.7.2 Group Replication Offline Upgrade">Section 18.7.2, “Group Replication Offline Upgrade”</a>. If your group
    needs to remain online, as is common with production deployments,
    see <a class="xref" href="group-replication.html#group-replication-online-upgrade" title="18.7.3 Group Replication Online Upgrade">Section 18.7.3, “Group Replication Online Upgrade”</a> for the
    different approaches available for upgrading a group with minimal
    downtime.
</p>
<div class="section">

<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="group-replication-online-upgrade-combining-versions"></a>18.7.1 Combining Different Member Versions in a Group</h3>

</div>

</div>

</div>

<div class="toc">
<dl class="toc"><dt><span class="section"><a href="group-replication.html#group-replication-compatibility-upgrade">18.7.1.1 Member Versions During Upgrades</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-compatibility-communication">18.7.1.2 Group Replication Communication Protocol Version</a></span></dt></dl>
</div>
<a class="indexterm" name="idm46444258393536"></a><p>
      Group Replication is versioned according to the MySQL Server
      version that the Group Replication plugin was bundled with. For
      example, if a member is running MySQL 5.7.26 then that is the
      version of the Group Replication plugin. To check the version of
      MySQL Server on a group member issue:
    </p><pre data-lang="sql" class="programlisting"><strong class="userinput"><code>SELECT MEMBER_HOST,MEMBER_PORT,MEMBER_VERSION FROM performance_schema.replication_group_members;</code></strong>
+-------------+-------------+----------------+
| member_host | member_port | member_version |
+-------------+-------------+----------------+
| example.com |	   3306     |   8.0.13	     |
+-------------+-------------+----------------+
      </pre><p>
      For guidance on understanding the MySQL Server version and
      selecting a version, see <a class="xref" href="installing.html#which-version" title="2.1.1 Which MySQL Version and Distribution to Install">Section 2.1.1, “Which MySQL Version and Distribution to Install”</a>.
    </p><p>
      For optimal compatibility and performance, all members of a group
      should run the same version of MySQL Server and therefore of Group
      Replication. However, while you are in the process of upgrading an
      online group, in order to maximize availability, you might need to
      have members with different MySQL Server versions running at the
      same time. Depending on the changes made between the versions of
      MySQL, you could encounter incompatibilities in this situation.
      For example, if a feature has been deprecated between major
      versions, then combining the versions in a group might cause
      members that rely on the deprecated feature to fail. Conversely,
      writing to a member running a newer MySQL version while there are
      read-write members in the group running an older MySQL version
      might cause issues on members that lack functions introduced in
      the newer release.
    </p><p>
      To prevent these issues, Group Replication includes compatibility
      policies that enable you to safely combine members running
      different versions of MySQL in the same group. A member applies
      these policies to decide whether to join the group normally, or
      join in read-only mode, or not join the group, depending on which
      choice results in the safe operation of the joining member and of
      the existing members of the group. In an upgrade scenario, each
      server must leave the group, be upgraded, and rejoin the group
      with its new server version. At this point the member applies the
      policies for its new server version, which might have changed from
      the policies it applied when it originally joined the group.
    </p><p>
      As the administrator, you can instruct any server to attempt to
      join any group by configuring the server appropriately and issuing
      a <a class="link" href="sql-statements.html#start-group-replication" title="13.4.3.1 START GROUP_REPLICATION Statement"><code class="literal">START GROUP_REPLICATION</code></a>
      statement. A decision to join or not join the group, or to join
      the group in read-only mode, is made and implemented by the
      joining member itself after you attempt to add it to the group.
      The joining member receives information on the MySQL Server
      versions of the current group members, assesses its own
      compatibility with those members, and applies the policies used in
      its own MySQL Server version (<span class="emphasis"><em>not</em></span> the
      policies used by the existing members) to decide whether it is
      compatible.
    </p><p>
      The compatibility policies that a joining member applies when
      attempting to join a group are as follows:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
          A member does not join a group if it is running a lower MySQL
          Server version than the lowest version that the existing group
          members are running.
        </p></li><li class="listitem"><p>
          A member joins a group normally if it is running the same
          MySQL Server version as the lowest version that the existing
          group members are running.
        </p></li><li class="listitem"><p>
          A member joins a group but remains in read-only mode if it is
          running a higher MySQL Server version than the lowest version
          that the existing group members are running. This behavior
          only makes a difference when the group is running in
          multi-primary mode, because in a group that is running in
          single-primary mode, newly added members default to being
          read-only in any case.
</p></li></ul>
</div>
<p>
      Members running MySQL 8.0.17 or higher take into account the patch
      version of the release when checking their compatibility. Members
      running MySQL 8.0.16 or lower, or MySQL 5.7, only take into
      account the major version. For example, if you have a group with
      members all running MySQL version 8.0.13:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
          A member that is running MySQL version 5.7 does not join.
        </p></li><li class="listitem"><p>
          A member running MySQL 8.0.16 joins normally (because it
          considers the major version).
        </p></li><li class="listitem"><p>
          A member running MySQL 8.0.17 joins but remains in read-only
          mode (because it considers the patch version).
</p></li></ul>
</div>
<p>
      Note that joining members running releases before MySQL 5.7.27
      check against all group members to find whether their own MySQL
      Server major version is lower. They therefore fail this check for
      a group where any members are running MySQL 8.0 releases, and
      cannot join the group even if it already has other members running
      MySQL 5.7. From MySQL 5.7.27, joining members only check against
      the group members that are running the lowest major version, so
      they can join a mixed version group where other MySQL 5.7 servers
      are present.
    </p><p>
      In a multi-primary mode group with members that use different
      MySQL Server versions, Group Replication automatically manages the
      read-write and read-only status of members running MySQL 8.0.17 or
      higher. If a member leaves the group, the members running the
      version that is now the lowest are automatically set to read-write
      mode. When you change a group that was running in single-primary
      mode to run in multi-primary mode, using the
      <a class="link" href="sql-statements.html#udf_group-replication-switch-to-multi-primary-mode"><code class="literal">group_replication_switch_to_multi_primary_mode()</code></a>
      UDF, Group Replication automatically sets members to the correct
      mode. Members are automatically placed in read-only mode if they
      are running a higher MySQL server version than the lowest version
      present in the group, and members running the lowest version are
      placed in read-write mode.
</p>
<div class="section">

<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="group-replication-compatibility-upgrade"></a>18.7.1.1 Member Versions During Upgrades</h4>
</div>
</div>
</div>
<p>
        During an online upgrade procedure, if the group is in
        single-primary mode, all the servers that are not currently
        offline for upgrading function as they did before. The group
        elects a new primary whenever necessary, following the election
        policies described in
        <a class="xref" href="group-replication.html#group-replication-single-primary-mode" title="18.1.3.1 Single-Primary Mode">Section 18.1.3.1, “Single-Primary Mode”</a>. Note
        that if you require the primary to remain the same throughout
        (except when it is being upgraded itself), you must first
        upgrade all of the secondaries to a version higher than or equal
        to the target primary member version, then upgrade the primary
        last. The primary cannot remain as the primary unless it is
        running the lowest MySQL Server version in the group. After the
        primary has been upgraded, you can use the
        <a class="link" href="sql-statements.html#udf_group-replication-set-as-primary"><code class="literal">group_replication_set_as_primary()</code></a>
        UDF to reappoint it as the primary.
      </p><p>
        If the group is in multi-primary mode, fewer online members are
        available to perform writes during the upgrade procedure,
        because upgraded members join in read-only mode after their
        upgrade. From MySQL 8.0.17, this applies to upgrades between
        patch versions, and for lower releases, this only applies to
        upgrades between major versions. When all members have been
        upgraded to the same release, from MySQL 8.0.17, they all change
        back to read-write mode automatically. For earlier releases, you
        must set <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only</code></a> to
        <code class="literal">OFF</code> manually on each member that should
        function as a primary following the upgrade.
      </p><p>
        To deal with a problem situation, for example if you have to
        roll back an upgrade or add extra capacity to a group in an
        emergency, it is possible to allow a member to join an online
        group although it is running a lower MySQL Server version than
        the lowest version in use by other group members. The Group
        Replication system variable
        <a class="link" href="group-replication.html#sysvar_group_replication_allow_local_lower_version_join"><code class="literal">group_replication_allow_local_lower_version_join</code></a>
        can be used in such situations to override the normal
        compatibility policies. It is important to note that setting the
        option to <code class="literal">ON</code> does not make the new member
        compatible with the group, and allows it to join the group
        without any safeguards against incompatible behaviors by the
        existing members. The option must therefore only be used
        carefully in specific situations, and you must take additional
        precautions to avoid the new member failing due to normal group
        activity. For details of these precautions, see the description
        for
        <a class="link" href="group-replication.html#sysvar_group_replication_allow_local_lower_version_join"><code class="literal">group_replication_allow_local_lower_version_join</code></a>.
</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="group-replication-compatibility-communication"></a>18.7.1.2 Group Replication Communication Protocol Version</h4>

</div>

</div>

</div>
<p>
        A replication group uses a Group Replication communication
        protocol version that can differ from the MySQL Server version
        of the members. To check the group's communication protocol
        version, issue the following statement on any member:
      </p><pre data-lang="sql" class="programlisting"><strong class="userinput"><code>SELECT group_replication_get_communication_protocol();</code></strong>
</pre><p>
        The return value shows the oldest MySQL Server version that can
        join this group and use the group's communication protocol.
        Versions from MySQL 5.7.14 allow compression of messages, and
        versions from MySQL 8.0.16 also allow fragmentation of messages.
        Note that the
        <a class="link" href="sql-statements.html#udf_group-replication-get-communication-protocol"><code class="literal">group_replication_get_communication_protocol()</code></a>
        UDF returns the minimum MySQL version that the group supports,
        which might differ from the version number that was passed to
        the
        <a class="link" href="sql-statements.html#udf_group-replication-set-communication-protocol"><code class="literal">group_replication_set_communication_protocol()</code></a>
        UDF, and from the MySQL Server version that is installed on the
        member where you use the UDF.
      </p><p>
        When you upgrade all the members of a replication group to a new
        MySQL Server release, the Group Replication communication
        protocol version is not automatically upgraded, in case there is
        still a requirement to allow members at earlier releases to
        join. If you do not need to support older members and want to
        allow the upgraded members to use any added communication
        capabilities, after the upgrade use the
        <a class="link" href="sql-statements.html#udf_group-replication-set-communication-protocol"><code class="literal">group_replication_set_communication_protocol()</code></a>
        UDF to upgrade the communication protocol, specifying the new
        MySQL Server version to which you have upgraded the members. For
        more information, see
        <a class="xref" href="group-replication.html#group-replication-communication-protocol" title="18.4.1.4 Setting a Group's Communication Protocol Version">Section 18.4.1.4, “Setting a Group's Communication Protocol Version”</a>.
</p>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="group-replication-offline-upgrade"></a>18.7.2 Group Replication Offline Upgrade</h3>

</div>

</div>

</div>
<a class="indexterm" name="idm46444258347888"></a><p>
      To perform an offline upgrade of a Group Replication group, you
      remove each member from the group, perform an upgrade of the
      member and then restart the group as usual. In a multi-primary
      group you can shutdown the members in any order. In a
      single-primary group, shutdown each secondary first and then
      finally the primary. See
      <a class="xref" href="group-replication.html#group-replication-upgrading-member" title="18.7.3.2 Upgrading a Group Replication Member">Section 18.7.3.2, “Upgrading a Group Replication Member”</a> for how to
      remove members from a group and shutdown MySQL.
    </p><p>
      Once the group is offline, upgrade all of the members. See
      <a class="xref" href="installing.html#upgrading" title="2.11 Upgrading MySQL">Section 2.11, “Upgrading MySQL”</a> for how to perform an upgrade. When
      all members have been upgraded, restart the members.
    </p><p>
      If you upgrade all the members of a replication group when they
      are offline and then restart the group, the members join using the
      new release's Group Replication communication protocol version, so
      that becomes the group's communication protocol version. If you
      have a requirement to allow members at earlier releases to join,
      you can use the
      <a class="link" href="sql-statements.html#udf_group-replication-set-communication-protocol"><code class="literal">group_replication_set_communication_protocol()</code></a>
      UDF to downgrade the communication protocol version, specifying
      the MySQL Server version of the prospective group member that has
      the oldest installed server version.
</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="group-replication-online-upgrade"></a>18.7.3 Group Replication Online Upgrade</h3>

</div>

</div>

</div>
<div class="toc">
<dl class="toc"><dt><span class="section"><a href="group-replication.html#group-replication-online-upgrade-considerations">18.7.3.1 Online Upgrade Considerations</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-upgrading-member">18.7.3.2 Upgrading a Group Replication Member</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-online-upgrade-methods">18.7.3.3 Group Replication Online Upgrade Methods</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-upgrade-with-mysqlbackup">18.7.3.4 Group Replication Upgrade with <span class="command"><strong>mysqlbackup</strong></span></a></span></dt></dl>
</div>
<a class="indexterm" name="idm46444258340016"></a><p>
      When you have a group running which you want to upgrade but you
      need to keep the group online to serve your application, you need
      to consider your approach to the upgrade. This section describes
      the different elements involved in an online upgrade, and various
      methods of how to upgrade your group.
</p>
<div class="section">

<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="group-replication-online-upgrade-considerations"></a>18.7.3.1 Online Upgrade Considerations</h4>
</div>
</div>
</div>
<a class="indexterm" name="idm46444258336560"></a><p>
        When upgrading an online group you should consider the following
        points:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            Regardless of the way which you upgrade your group, it is
            important to disable any writes to group members until they
            are ready to rejoin the group.
          </p></li><li class="listitem"><p>
            When a member is stopped, the
            <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only</code></a> variable is
            set to on automatically, but this change is not persisted.
          </p></li><li class="listitem"><p>
            When MySQL 5.7.22 or MySQL 8.0.11 tries to join a group
            running MySQL 5.7.21 or lower it fails to join the group
            because MySQL 5.7.21 does not send its value of
            <a class="link" href="server-administration.html#sysvar_lower_case_table_names"><code class="literal">lower_case_table_names</code></a>.
</p></li></ul>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="group-replication-upgrading-member"></a>18.7.3.2 Upgrading a Group Replication Member</h4>

</div>

</div>

</div>
<a class="indexterm" name="idm46444258327648"></a><p>
        This section explains the steps required for upgrading a member
        of a group. This procedure is part of the methods described at
        <a class="xref" href="group-replication.html#group-replication-online-upgrade-methods" title="18.7.3.3 Group Replication Online Upgrade Methods">Section 18.7.3.3, “Group Replication Online Upgrade Methods”</a>. The
        process of upgrading a member of a group is common to all
        methods and is explained first. The way which you join upgraded
        members can depend on which method you are following, and other
        factors such as whether the group is operating in single-primary
        or multi-primary mode. How you upgrade the server instance,
        using either the in-place or provision approach, does not impact
        on the methods described here.
      </p><p>
        The process of upgrading a member consists of removing it from
        the group, following your chosen method of upgrading the member,
        and then rejoining the upgraded member to a group. The
        recommended order of upgrading members in a single-primary group
        is to upgrade all secondaries, and then upgrade the primary
        last. If the primary is upgraded before a secondary, a new
        primary using the older MySQL version is chosen, but there is no
        need for this step.
      </p><p>
        To upgrade a member of a group:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            Connect a client to the group member and issue
            <a class="link" href="sql-statements.html#stop-group-replication" title="13.4.3.2 STOP GROUP_REPLICATION Statement"><code class="literal">STOP GROUP_REPLICATION</code></a>.
            Before proceeding, ensure that the member's status is
            <code class="literal">OFFLINE</code> by monitoring the
            <a class="link" href="performance-schema.html#replication-group-members-table" title="26.12.11.9 The replication_group_members Table"><code class="literal">replication_group_members</code></a>
            table.
          </p></li><li class="listitem"><p>
            Disable Group Replication from starting up automatically so
            that you can safely connect to the member after upgrading
            and configure it without it rejoining the group by setting
            <a class="link" href="group-replication.html#sysvar_group_replication_start_on_boot"><code class="literal">
            group_replication_start_on_boot=0</code></a>.
</p>
<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Important
</div>
<p>
              If an upgraded member has <a class="link" href="group-replication.html#sysvar_group_replication_start_on_boot"><code class="literal">
              group_replication_start_on_boot=1</code></a> then it could
              rejoin the group before you can perform the MySQL upgrade
              procedure and could result in issues. For example, if the
              upgrade fails and the server restarts again, then a
              possibly broken server could try to join the group.
</p>
</div>
</li><li class="listitem"><p>
            Stop the member, for example using <a class="link" href="programs.html#mysqladmin" title="4.5.2 mysqladmin — Client for Administering a MySQL Server"><span class="command"><strong>mysqladmin
            shutdown</strong></span></a> or the
            <a class="link" href="sql-statements.html#shutdown" title="13.7.8.9 SHUTDOWN Statement"><code class="literal">SHUTDOWN</code></a> statement. Any other
            members in the group continue running.
          </p></li><li class="listitem"><p>
            Upgrade the member, using the in-place or provisioning
            approach. See <a class="xref" href="installing.html#upgrading" title="2.11 Upgrading MySQL">Section 2.11, “Upgrading MySQL”</a> for details. When
            restarting the upgraded member, because
            <a class="link" href="group-replication.html#sysvar_group_replication_start_on_boot"><code class="literal">
            group_replication_start_on_boot</code></a> is set to 0, Group
            Replication does not start on the instance, and therefore it
            does not rejoin the group.
          </p></li><li class="listitem"><p>
            Once the MySQL upgrade procedure has been performed on the
            member,
            <a class="link" href="group-replication.html#sysvar_group_replication_start_on_boot"><code class="literal">group_replication_start_on_boot</code></a>
            must be set to 1 to ensure Group Replication starts
            correctly after restart. Restart the member.
          </p></li><li class="listitem"><p>
            Connect to the upgraded member and issue
            <a class="link" href="sql-statements.html#start-group-replication" title="13.4.3.1 START GROUP_REPLICATION Statement"><code class="literal">START GROUP_REPLICATION</code></a>. This
            rejoins the member to the group. The Group Replication
            metadata is in place on the upgraded server, therefore there
            is usually no need to reconfigure Group Replication. The
            server has to catch up with any transactions processed by
            the group while the server was offline. Once it has caught
            up with the group, it becomes an online member of the group.
</p>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Note
</div>
<p>
              The longer it takes to upgrade a server, the more time
              that member is offline and therefore the more time it
              takes for the server to catch up when added back to the
              group.
</p>
</div>
</li></ul>
</div>
<p>
        When an upgraded member joins a group which has any member
        running an earlier MySQL Server version, the upgraded member
        joins with <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only=on</code></a>.
        This ensures that no writes are made to upgraded members until
        all members are running the newer version. In a multi-primary
        mode group, when the upgrade has been completed successfully and
        the group is ready to process transactions, members that are
        intended as writeable primaries must be set to read-write mode.
        From MySQL 8.0.17, when all members of a group have been
        upgraded to the same release, they all change back to read-write
        mode automatically. For earlier releases you must set each
        member manually to read-write mode. Connect to each member and
        issue:
</p><pre data-lang="sql" class="programlisting"><strong class="userinput"><code>SET GLOBAL super_read_only=OFF;</code></strong></pre>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="group-replication-online-upgrade-methods"></a>18.7.3.3 Group Replication Online Upgrade Methods</h4>

</div>

</div>

</div>
<a class="indexterm" name="idm46444258296208"></a><p>
        Choose one of the following methods of upgrading a Group
        Replication group:
</p>
<div class="simplesect">

<div class="titlepage">
<div>

<div class="simple">
<h5 class="title"><a name="group-replication-upgrading-rolling-in-group"></a>Rolling In-Group Upgrade</h5>
</div>
</div>
</div>
<p>
          

          This method is supported provided that servers running a newer
          version are not generating workload to the group while there
          are still servers with an older version in it. In other words
          servers with a newer version can join the group only as
          secondaries. In this method there is only ever one group, and
          each server instance is removed from the group, upgraded and
          then rejoined to the group.
        </p><p>
          This method is well suited to single-primary groups. When the
          group is operating in single-primary mode, if you require the
          primary to remain the same throughout (except when it is being
          upgraded itself), it should be the last member to be upgraded.
          The primary cannot remain as the primary unless it is running
          the lowest MySQL Server version in the group. After the
          primary has been upgraded, you can use the
          <a class="link" href="sql-statements.html#udf_group-replication-set-as-primary"><code class="literal">group_replication_set_as_primary()</code></a>
          UDF to reappoint it as the primary. If you do not mind which
          member is the primary, the members can be upgraded in any
          order. The group elects a new primary whenever necessary from
          among the members running the lowest MySQL Server version,
          following the election policies described in
          <a class="xref" href="group-replication.html#group-replication-single-primary-mode" title="18.1.3.1 Single-Primary Mode">Section 18.1.3.1, “Single-Primary Mode”</a>.
        </p><p>
          For groups operating in multi-primary mode, during a rolling
          in-group upgrade the number of primaries is decreased, causing
          a reduction in write availability. This is because if a member
          joins a group when it is running a higher MySQL Server version
          than the lowest version that the existing group members are
          running, it automatically remains in read-only mode
          (<a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only=ON</code></a>). Note
          that members running MySQL 8.0.17 or higher take into account
          the patch version of the release when checking this, but
          members running MySQL 8.0.16 or lower, or MySQL 5.7, only take
          into account the major version. When all members have been
          upgraded to the same release, from MySQL 8.0.17, they all
          change back to read-write mode automatically. For earlier
          releases, you must set
          <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only=OFF</code></a> manually
          on each member that should function as a primary following the
          upgrade.
        </p><p>
          For full information on version compatibility in a group and
          how this influences the behavior of a group during an upgrade
          process, see
          <a class="xref" href="group-replication.html#group-replication-online-upgrade-combining-versions" title="18.7.1 Combining Different Member Versions in a Group">Section 18.7.1, “Combining Different Member Versions in a Group”</a>
          .
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h5 class="title"><a name="group-replication-upgrading-rolling-migration"></a>Rolling Migration Upgrade</h5>

</div>

</div>

</div>
<p>
          

          In this method you remove members from the group, upgrade them
          and then create a second group using the upgraded members. For
          groups operating in multi-primary mode, during this process
          the number of primaries is decreased, causing a reduction in
          write availability. This does not impact groups operating in
          single-primary mode.
        </p><p>
          Because the group running the older version is online while
          you are upgrading the members, you need the group running the
          newer version to catch up with any transactions executed while
          the members were being upgraded. Therefore one of the servers
          in the new group is configured as a replication slave of a
          primary from the older group. This ensures that the new group
          catches up with the older group. Because this method relies on
          an asynchronous replication channel which is used to replicate
          data from one group to another, it is supported under the same
          assumptions and requirements of master-slave replication, see
          <a class="xref" href="replication.html" title="Chapter 17 Replication">Chapter 17, <i>Replication</i></a>. For groups operating in
          single-primary mode, the asynchronous replication connection
          to the old group must send data to the primary in the new
          group, for a multi-primary group the asynchronous replication
          channel can connect to any primary.
        </p><p>
          The process is to:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              remove members from the original group running the older
              server version one by one, see
              <a class="xref" href="group-replication.html#group-replication-upgrading-member" title="18.7.3.2 Upgrading a Group Replication Member">Section 18.7.3.2, “Upgrading a Group Replication Member”</a>
            </p></li><li class="listitem"><p>
              upgrade the server version running on the member, see
              <a class="xref" href="installing.html#upgrading" title="2.11 Upgrading MySQL">Section 2.11, “Upgrading MySQL”</a>. You can either follow an
              in-place or provision approach to upgrading.
            </p></li><li class="listitem"><p>
              create a new group with the upgraded members, see
              <a class="xref" href="group-replication.html" title="Chapter 18 Group Replication">Chapter 18, <i>Group Replication</i></a>. In this case you need
              to configure a new group name on each member (because the
              old group is still running and using the old name),
              bootstrap an initial upgraded member, and then add the
              remaining upgraded members.
            </p></li><li class="listitem"><p>
              set up an asynchronous replication channel between the old
              group and the new group, see
              <a class="xref" href="replication.html#replication-gtids-howto" title="17.1.3.4 Setting Up Replication Using GTIDs">Section 17.1.3.4, “Setting Up Replication Using GTIDs”</a>. Configure the
              older primary to function as the asynchronous replication
              master and the new group member as a GTID-based
              replication slave.
</p></li></ul>
</div>
<p>
          Before you can redirect your application to the new group, you
          must ensure that the new group has a suitable number of
          members, for example so that the group can handle the failure
          of a member. Issue <code class="literal">SELECT * FROM
          performance_schema.replication_group_members</code> and
          compare the initial group size and the new group size. Wait
          until all data from the old group is propagated to the new
          group and then drop the asynchronous replication connection
          and upgrade any missing members.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h5 class="title"><a name="group-replication-upgrading-rolling-duplication"></a>Rolling Duplication Upgrade</h5>

</div>

</div>

</div>
<p>
          

          In this method you create a second group consisting of members
          which are running the newer version, and the data missing from
          the older group is replicated to the newer group. This assumes
          that you have enough servers to run both groups
          simultaneously. Due to the fact that during this process the
          number of primaries is <span class="emphasis"><em>not</em></span> decreased, for
          groups operating in multi-primary mode there is no reduction
          in write availability. This makes rolling duplication upgrade
          well suited to groups operating in multi-primary mode. This
          does not impact groups operating in single-primary mode.
        </p><p>
          Because the group running the older version is online while
          you are provisioning the members in the new group, you need
          the group running the newer version to catch up with any
          transactions executed while the members were being
          provisioned. Therefore one of the servers in the new group is
          configured as a replication slave of a primary from the older
          group. This ensures that the new group catches up with the
          older group. Because this method relies on an asynchronous
          replication channel which is used to replicate data from one
          group to another, it is supported under the same assumptions
          and requirements of master-slave replication, see
          <a class="xref" href="replication.html" title="Chapter 17 Replication">Chapter 17, <i>Replication</i></a>. For groups operating in
          single-primary mode, the asynchronous replication connection
          to the old group must send data to the primary in the new
          group, for a multi-primary group the asynchronous replication
          channel can connect to any primary.
        </p><p>
          The process is to:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              deploy a suitable number of members so that the group
              running the newer version can handle failure of a member
            </p></li><li class="listitem"><p>
              take a backup of the existing data from a member of the
              group
            </p></li><li class="listitem"><p>
              use the backup from the older member to provision the
              members of the new group, see
              <a class="xref" href="group-replication.html#group-replication-upgrade-with-mysqlbackup" title="18.7.3.4 Group Replication Upgrade with mysqlbackup">Section 18.7.3.4, “Group Replication Upgrade with <span class="command"><strong>mysqlbackup</strong></span>”</a>
              for one method.
</p>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Note
</div>
<p>
                You must restore the backup to the same version of MySQL
                which the backup was taken from, and then perform an
                in-place upgrade. For instructions, see
                <a class="xref" href="installing.html#upgrading" title="2.11 Upgrading MySQL">Section 2.11, “Upgrading MySQL”</a>.
</p>
</div>
</li><li class="listitem"><p>
              create a new group with the upgraded members, see
              <a class="xref" href="group-replication.html" title="Chapter 18 Group Replication">Chapter 18, <i>Group Replication</i></a>. In this case you need
              to configure a new group name on each member (because the
              old group is still running and using the old name),
              bootstrap an initial upgraded member, and then add the
              remaining upgraded members.
            </p></li><li class="listitem"><p>
              set up an asynchronous replication channel between the old
              group and the new group, see
              <a class="xref" href="replication.html#replication-gtids-howto" title="17.1.3.4 Setting Up Replication Using GTIDs">Section 17.1.3.4, “Setting Up Replication Using GTIDs”</a>. Configure the
              older primary to function as the asynchronous replication
              master and the new group member as a GTID-based
              replication slave.
</p></li></ul>
</div>
<p>
          Once the ongoing data missing from the newer group is small
          enough to be quickly transferred, you must redirect write
          operations to the new group. Wait until all data from the old
          group is propagated to the new group and then drop the
          asynchronous replication connection.
</p>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="group-replication-upgrade-with-mysqlbackup"></a>18.7.3.4 Group Replication Upgrade with <span class="command"><strong>mysqlbackup</strong></span></h4>

</div>

</div>

</div>
<p>
        As part of a provisioning approach you can use MySQL Enterprise Backup to copy and
        restore the data from a group member to new members. However you
        cannot use this technique to directly restore a backup taken
        from a member running an older version of MySQL to a member
        running a newer version of MySQL. The solution is to restore the
        backup to a new server instance which is running the same
        version of MySQL as the member which the backup was taken from,
        and then upgrade the instance. This process consists of:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            Take a backup from a member of the older group using
            <span class="command"><strong>mysqlbackup</strong></span>. See
            <a class="xref" href="group-replication.html#group-replication-enterprise-backup" title="18.4.6 Using MySQL Enterprise Backup with Group Replication">Section 18.4.6, “Using MySQL Enterprise Backup with Group Replication”</a>.
          </p></li><li class="listitem"><p>
            Deploy a new server instance, which must be running the same
            version of MySQL as the older member where the backup was
            taken.
          </p></li><li class="listitem"><p>
            Restore the backup from the older member to the new instance
            using <span class="command"><strong>mysqlbackup</strong></span>.
          </p></li><li class="listitem"><p>
            Upgrade MySQL on the new instance, see
            <a class="xref" href="installing.html#upgrading" title="2.11 Upgrading MySQL">Section 2.11, “Upgrading MySQL”</a>.
</p></li></ul>
</div>
<p>
        Repeat this process to create a suitable number of new
        instances, for example to be able to handle a failover. Then
        join the instances to a group based on the
        <a class="xref" href="group-replication.html#group-replication-online-upgrade-methods" title="18.7.3.3 Group Replication Online Upgrade Methods">Section 18.7.3.3, “Group Replication Online Upgrade Methods”</a>.`
</p>
</div>

</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a name="group-replication-options"></a>18.8 Group Replication System Variables</h2>

</div>

</div>

</div>
<a class="indexterm" name="idm46444258240656"></a><p>
    This section lists the system variables that are specific to the
    Group Replication plugin. Every configuration option is prefixed
    with "<code class="literal">group_replication</code>".
  </p><p>
    Most system variables for Group Replication are described as
    dynamic, and their values can be changed while the server is
    running. However, in most cases, the change only takes effect after
    you stop and restart Group Replication on the group member using a
    <a class="link" href="sql-statements.html#stop-group-replication" title="13.4.3.2 STOP GROUP_REPLICATION Statement"><code class="literal">STOP GROUP_REPLICATION</code></a> statement
    followed by a <a class="link" href="sql-statements.html#start-group-replication" title="13.4.3.1 START GROUP_REPLICATION Statement"><code class="literal">START GROUP_REPLICATION</code></a>
    statement. Changes to the following system variables take effect
    without stopping and restarting Group Replication:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
        <a class="link" href="group-replication.html#sysvar_group_replication_flow_control_applier_threshold"><code class="literal">group_replication_flow_control_applier_threshold</code></a>
      </p></li><li class="listitem"><p>
        <a class="link" href="group-replication.html#sysvar_group_replication_flow_control_certifier_threshold"><code class="literal">group_replication_flow_control_certifier_threshold</code></a>
      </p></li><li class="listitem"><p>
        <a class="link" href="group-replication.html#sysvar_group_replication_flow_control_mode"><code class="literal">group_replication_flow_control_mode</code></a>
</p></li></ul>
</div>
<p>
    Most system variables for Group Replication can have different
    values on different group members. For the following system
    variables, it is advisable to set the same value on all members of a
    group in order to avoid unnecessary rollback of transactions,
    failure of message delivery, or failure of message recovery:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
        <a class="link" href="group-replication.html#sysvar_group_replication_auto_increment_increment"><code class="literal">group_replication_auto_increment_increment</code></a>
      </p></li><li class="listitem"><p>
        <a class="link" href="group-replication.html#sysvar_group_replication_communication_max_message_size"><code class="literal">group_replication_communication_max_message_size</code></a>
      </p></li><li class="listitem"><p>
        <a class="link" href="group-replication.html#sysvar_group_replication_compression_threshold"><code class="literal">group_replication_compression_threshold</code></a>
      </p></li><li class="listitem"><p>
        <a class="link" href="group-replication.html#sysvar_group_replication_message_cache_size"><code class="literal">group_replication_message_cache_size</code></a>
      </p></li><li class="listitem"><p>
        <a class="link" href="group-replication.html#sysvar_group_replication_transaction_size_limit"><code class="literal">group_replication_transaction_size_limit</code></a>
</p></li></ul>
</div>
<p>
    Some system variables on a Group Replication group member, including
    some Group Replication-specific system variables and some general
    system variables, are group-wide configuration settings. These
    system variables must have the same value on all group members,
    cannot be changed while Group Replication is running, and require a
    full reboot of the group (a bootstrap by a server with
    <a class="link" href="group-replication.html#sysvar_group_replication_bootstrap_group"><code class="literal">group_replication_bootstrap_group=ON</code></a>)
    in order for the value change to take effect. These conditions apply
    to the following system variables:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
        <a class="link" href="group-replication.html#sysvar_group_replication_single_primary_mode"><code class="literal">group_replication_single_primary_mode</code></a>
      </p></li><li class="listitem"><p>
        <a class="link" href="group-replication.html#sysvar_group_replication_enforce_update_everywhere_checks"><code class="literal">group_replication_enforce_update_everywhere_checks</code></a>
      </p></li><li class="listitem"><p>
        <a class="link" href="group-replication.html#sysvar_group_replication_gtid_assignment_block_size"><code class="literal">group_replication_gtid_assignment_block_size</code></a>
      </p></li><li class="listitem"><p>
        <a class="link" href="server-administration.html#sysvar_default_table_encryption"><code class="literal">default_table_encryption</code></a>
      </p></li><li class="listitem"><p>
        <a class="link" href="server-administration.html#sysvar_lower_case_table_names"><code class="literal">lower_case_table_names</code></a>
      </p></li><li class="listitem"><p>
        <a class="link" href="replication.html#sysvar_transaction_write_set_extraction"><code class="literal">transaction_write_set_extraction</code></a>
</p></li></ul>
</div>
<p>
    From MySQL 8.0.16, you can use the
    <a class="link" href="sql-statements.html#udf_group-replication-switch-to-single-primary-mode"><code class="literal">group_replication_switch_to_single_primary_mode()</code></a>
    and
    <a class="link" href="sql-statements.html#udf_group-replication-switch-to-multi-primary-mode"><code class="literal">group_replication_switch_to_multi_primary_mode()</code></a>
    UDFs to change the values of
    <a class="link" href="group-replication.html#sysvar_group_replication_single_primary_mode"><code class="literal">group_replication_single_primary_mode</code></a>
    and
    <a class="link" href="group-replication.html#sysvar_group_replication_enforce_update_everywhere_checks"><code class="literal">group_replication_enforce_update_everywhere_checks</code></a>
    while the group is still running. For more information, see
    <a class="xref" href="group-replication.html#group-replication-changing-group-mode" title="18.4.1.2 Changing a Group's Mode">Section 18.4.1.2, “Changing a Group's Mode”</a>.
</p>
<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Important
</div>

<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
          A number of system variables for Group Replication are not
          completely validated during server startup if they are passed
          as command line arguments to the server. These system
          variables include
          <a class="link" href="group-replication.html#sysvar_group_replication_group_name"><code class="literal">group_replication_group_name</code></a>,
          <a class="link" href="group-replication.html#sysvar_group_replication_single_primary_mode"><code class="literal">group_replication_single_primary_mode</code></a>,
          <a class="link" href="group-replication.html#sysvar_group_replication_force_members"><code class="literal">group_replication_force_members</code></a>,
          the SSL variables, and the flow control system variables. They
          are only fully validated after the server has started.
        </p></li><li class="listitem"><p>
          System variables for Group Replication that specify IP
          addresses or host names for group members are not validated
          until a <a class="link" href="sql-statements.html#start-group-replication" title="13.4.3.1 START GROUP_REPLICATION Statement"><code class="literal">START GROUP_REPLICATION</code></a>
          statement is issued. Group Replication's Group Communication
          System (GCS) is not available to validate the values until
          that point.
</p></li></ul>
</div>

</div>
<p>
    The system variables that are specific to the Group Replication
    plugin are as follows:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p><a name="sysvar_group_replication_allow_local_lower_version_join"></a>
        <a class="indexterm" name="idm46444258185360"></a>

        <a class="indexterm" name="idm46444258184240"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_allow_local_lower_version_join"><code class="literal">group_replication_allow_local_lower_version_join</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_allow_local_lower_version_join"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-allow-local-lower-version-join[={OFF|ON}]</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_allow_local_lower_version_join">group_replication_allow_local_lower_version_join</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>Boolean</td>
</tr><tr><td scope="row"><span class="bold"><strong>Default Value</strong></span></td>
<td><code class="literal">OFF</code></td>
</tr></tbody></table>
</div>
<p>
        Allows the current server to join the group even if it is
        running a lower MySQL Server version than the group. With the
        default setting <code class="literal">OFF</code>, servers are not
        permitted to join a replication group if they are running a
        lower version than the existing group members. This standard
        policy ensures that all members of a group are able to exchange
        messages and apply transactions. Note that members running MySQL
        8.0.17 or higher take into account the patch version of the
        release when checking their compatibility. Members running MySQL
        8.0.16 or lower, or MySQL 5.7, only take into account the major
        version.
      </p><p>
        Set
        <a class="link" href="group-replication.html#sysvar_group_replication_allow_local_lower_version_join"><code class="literal">group_replication_allow_local_lower_version_join</code></a>
        to <code class="literal">ON</code> only in the following scenarios:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
            A server must be added to the group in an emergency in order
            to improve the group's fault tolerance, and only older
            versions are available.
          </p></li><li class="listitem"><p>
            You want to roll back an upgrade for one or more replication
            group members without shutting down the whole group and
            bootstrapping it again.
</p></li></ul>
</div>
<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;">
<div class="admon-title">
Warning
</div>
<p>
          Setting this option to <code class="literal">ON</code> does not make the
          new member compatible with the group, and allows it to join
          the group without any safeguards against incompatible
          behaviors by the existing members. To ensure the new member's
          correct operation, take <span class="emphasis"><em>both</em></span> of the
          following precautions:
</p>
<div class="orderedlist">
<ol class="orderedlist" type="1"><li class="listitem"><p>
              Before the server running the lower version joins the
              group, stop all writes on that server.
            </p></li><li class="listitem"><p>
              From the point where the server running the lower version
              joins the group, stop all writes on the other servers in
              the group.
</p></li></ol>
</div>
<p>
          Without these precautions, the server running the lower
          version is likely to experience difficulties and terminate
          with an error.
</p>
</div>
</li><li class="listitem"><p><a name="sysvar_group_replication_auto_increment_increment"></a>
        <a class="indexterm" name="idm46444258140384"></a>

        <a class="indexterm" name="idm46444258139264"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_auto_increment_increment"><code class="literal">group_replication_auto_increment_increment</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_auto_increment_increment"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-auto-increment-increment=#</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_auto_increment_increment">group_replication_auto_increment_increment</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>Integer</td>
</tr><tr><td scope="row"><span class="bold"><strong>Default Value</strong></span></td>
<td><code class="literal">7</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Minimum Value</strong></span></td>
<td><code class="literal">1</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Maximum Value</strong></span></td>
<td><code class="literal">65535</code></td>
</tr></tbody></table>
</div>
<p>
        Determines the interval between successive column values for
        transactions that execute on this server instance. This system
        variable should have the same value on all group members. When
        Group Replication is started on a server, the value of the
        server system variable
        <a class="link" href="replication.html#sysvar_auto_increment_increment"><code class="literal">auto_increment_increment</code></a> is
        changed to this value, and the value of the server system
        variable <a class="link" href="replication.html#sysvar_auto_increment_offset"><code class="literal">auto_increment_offset</code></a>
        is changed to the server ID. These settings avoid the selection
        of duplicate auto-increment values for writes on group members,
        which causes rollback of transactions. The changes are reverted
        when Group Replication is stopped. These changes are only made
        and reverted if
        <a class="link" href="replication.html#sysvar_auto_increment_increment"><code class="literal">auto_increment_increment</code></a> and
        <a class="link" href="replication.html#sysvar_auto_increment_offset"><code class="literal">auto_increment_offset</code></a> each have
        their default value of 1. If their values have already been
        modified from the default, Group Replication does not alter
        them. From MySQL 8.0, the system variables are also not modified
        when Group Replication is in single-primary mode, where only one
        server writes.
      </p><p>
        The default value of 7 represents a balance between the number
        of usable values and the permitted maximum size of a replication
        group (9 members). If your group has more or fewer members, you
        can set this system variable to match the expected number of
        group members before Group Replication is started. You cannot
        change the setting while Group Replication is running.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_autorejoin_tries"></a>
        <a class="indexterm" name="idm46444258094160"></a>

        <a class="indexterm" name="idm46444258093120"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_autorejoin_tries"><code class="literal">group_replication_autorejoin_tries</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_autorejoin_tries"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-autorejoin-tries=#</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Introduced</strong></span></td>
<td>8.0.16</td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_autorejoin_tries">group_replication_autorejoin_tries</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>Integer</td>
</tr><tr><td scope="row"><span class="bold"><strong>Default Value</strong></span></td>
<td><code class="literal">0</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Minimum Value</strong></span></td>
<td><code class="literal">0</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Maximum Value</strong></span></td>
<td><code class="literal">2016</code></td>
</tr></tbody></table>
</div>
<p>
        Specifies the number of tries that a member makes to
        automatically rejoin the group if it is expelled, or if it is
        unable to contact a majority of the group before the
        <a class="link" href="group-replication.html#sysvar_group_replication_unreachable_majority_timeout"><code class="literal">group_replication_unreachable_majority_timeout</code></a>
        setting is reached. The default setting, 0, means that the
        member does not try to rejoin, and proceeds to the action
        specified by the
        <a class="link" href="group-replication.html#sysvar_group_replication_exit_state_action"><code class="literal">group_replication_exit_state_action</code></a>
        system variable. You can specify a maximum of 2016 tries.
      </p><p>
        If you specify a number of tries, when the member's expulsion or
        unreachable majority timeout is reached, it makes an attempt to
        rejoin (using the current plugin option values), then continues
        to make further auto-rejoin attempts up to the specified number
        of tries. After an unsuccessful auto-rejoin attempt, the member
        waits 5 minutes before the next try. During the auto-rejoin
        procedure, the member remains in super read only mode and
        displays an <code class="literal">ERROR</code> state on its view of the
        replication group. The member can be stopped manually at any
        time by using a <a class="link" href="sql-statements.html#stop-group-replication" title="13.4.3.2 STOP GROUP_REPLICATION Statement"><code class="literal">STOP
        GROUP_REPLICATION</code></a> statement or shutting down the
        server. If the specified number of tries is exhausted without
        the member rejoining or being stopped, the member proceeds to
        the action specified by the
        <a class="link" href="group-replication.html#sysvar_group_replication_exit_state_action"><code class="literal">group_replication_exit_state_action</code></a>
        system variable.
      </p><p>
        For more information on using this option, see
        <a class="xref" href="group-replication.html#group-replication-responses-failure-rejoin" title="18.6.6.3 Auto-Rejoin">Section 18.6.6.3, “Auto-Rejoin”</a>.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_bootstrap_group"></a>
        <a class="indexterm" name="idm46444258043392"></a>

        <a class="indexterm" name="idm46444258042352"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_bootstrap_group"><code class="literal">group_replication_bootstrap_group</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_bootstrap_group"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-bootstrap-group[={OFF|ON}]</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_bootstrap_group">group_replication_bootstrap_group</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>Boolean</td>
</tr><tr><td scope="row"><span class="bold"><strong>Default Value</strong></span></td>
<td><code class="literal">OFF</code></td>
</tr></tbody></table>
</div>
<p>
        Configure this server to bootstrap the group. This option must
        only be set on one server and only when starting the group for
        the first time or restarting the entire group. After the group
        has been bootstrapped, set this option to
        <code class="literal">OFF</code>. It should be set to
        <code class="literal">OFF</code> both dynamically and in the configuration
        files. Starting two servers or restarting one server with this
        option set while the group is running may lead to an artificial
        split brain situation, where two independent groups with the
        same name are bootstrapped.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_clone_threshold"></a>
        <a class="indexterm" name="idm46444258008400"></a>

        <a class="indexterm" name="idm46444258007360"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_clone_threshold"><code class="literal">group_replication_clone_threshold</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_clone_threshold"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-clone-threshold=#</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Introduced</strong></span></td>
<td>8.0.17</td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_clone_threshold">group_replication_clone_threshold</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>Integer</td>
</tr><tr><td scope="row"><span class="bold"><strong>Default Value</strong></span></td>
<td><code class="literal">9223372036854775807</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Minimum Value</strong></span></td>
<td><code class="literal">1</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Maximum Value</strong></span></td>
<td><code class="literal">9223372036854775807</code></td>
</tr></tbody></table>
</div>
<p>
        The transaction gap, as a number of transactions, between the
        existing member (donor) and the joining member (recipient) that
        triggers the use of a remote cloning operation for state
        transfer to the joining member during the distributed recovery
        process. If the transaction gap between the joining member and a
        suitable donor exceeds the threshold, Group Replication begins
        distributed recovery with a remote cloning operation. If the
        transaction gap is below the threshold, or if the remote cloning
        operation is not technically possible, Group Replication
        proceeds directly to state transfer from a donor's binary log.
</p>
<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Warning
</div>
<p>
          Do not use a low setting for
          <a class="link" href="group-replication.html#sysvar_group_replication_clone_threshold"><code class="literal">group_replication_clone_threshold</code></a>
          in an active group. If a number of transactions above the
          threshold takes place in the group while the remote cloning
          operation is in progress, the joining member triggers a remote
          cloning operation again after restarting, and could continue
          this indefinitely. To avoid this situation, ensure that you
          set the threshold to a number higher than the number of
          transactions that you would expect to occur in the group
          during the time taken for the remote cloning operation.
</p>
</div>
<p>
        To use this function, both the donor and the joining member must
        be set up beforehand to support cloning. For instructions, see
        <a class="xref" href="group-replication.html#group-replication-cloning" title="18.4.3.1 Cloning for Distributed Recovery">Section 18.4.3.1, “Cloning for Distributed Recovery”</a>. When a remote
        cloning operation is carried out, Group Replication manages it
        for you, including the required server restart, provided that
        <a class="link" href="group-replication.html#sysvar_group_replication_start_on_boot"><code class="literal">group_replication_start_on_boot=ON</code></a>
        is set. If not, you must restart the server manually. The remote
        cloning operation replaces the existing data dictionary on the
        joining member, but Group Replication checks and does not
        proceed if the joining member has additional transactions that
        are not present on the other group members, because these
        transactions would be erased by the cloning operation.
      </p><p>
        The default setting (which is the maximum permitted sequence
        number for a transaction in a GTID) means that state transfer
        from a donor's binary log will virtually always be attempted
        rather than cloning. However, note that Group Replication always
        attempts to execute a cloning operation, regardless of your
        threshold, if state transfer from a donor's binary log is
        impossible, for example because the transactions needed by the
        joining member are not available in the binary logs on any
        existing group member. If you do not want to use cloning at all
        in your replication group, do not install the clone plugin on
        the members.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_communication_debug_options"></a>
        <a class="indexterm" name="idm46444257958848"></a>

        <a class="indexterm" name="idm46444257957728"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_communication_debug_options"><code class="literal">group_replication_communication_debug_options</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_communication_debug_options"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-communication-debug-options=value</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_communication_debug_options">group_replication_communication_debug_options</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>String</td>
</tr><tr><td scope="row"><span class="bold"><strong>Default Value</strong></span></td>
<td><code class="literal">GCS_DEBUG_NONE</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Valid Values</strong></span></td>
<td><p class="valid-value"><code class="literal">GCS_DEBUG_NONE</code></p><p class="valid-value"><code class="literal">GCS_DEBUG_BASIC</code></p><p class="valid-value"><code class="literal">GCS_DEBUG_TRACE</code></p><p class="valid-value"><code class="literal">XCOM_DEBUG_BASIC</code></p><p class="valid-value"><code class="literal">XCOM_DEBUG_TRACE</code></p><p class="valid-value"><code class="literal">GCS_DEBUG_ALL</code></p></td>
</tr></tbody></table>
</div>
<p>
        Configures the level of debugging messages to provide for the
        different Group Replication components, such as Group
        Communication System (GCS) and the group communication engine
        (XCom, a Paxos variant). The debug information is stored in the
        <code class="filename">GCS_DEBUG_TRACE</code> file in the data directory.
      </p><p>
        The set of available options, specified as strings, can be
        combined. The following options are available:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
            <code class="literal">GCS_DEBUG_NONE</code> disables all debugging
            levels for both GCS and XCOM
          </p></li><li class="listitem"><p>
            <code class="literal">GCS_DEBUG_BASIC</code> enables basic debugging
            information in GCS
          </p></li><li class="listitem"><p>
            <code class="literal">GCS_DEBUG_TRACE</code> enables trace information
            in GCS
          </p></li><li class="listitem"><p>
            <code class="literal">XCOM_DEBUG_BASIC</code> enables basic debugging
            information in XCOM
          </p></li><li class="listitem"><p>
            <code class="literal">XCOM_DEBUG_TRACE</code> enables trace
            information in XCOM
          </p></li><li class="listitem"><p>
            <code class="literal">GCS_DEBUG_ALL</code> enables all debugging
            levels for both GCS and XCOM
</p></li></ul>
</div>
<p>
        Setting the debug level to <code class="literal">GCS_DEBUG_NONE</code>
        only has an effect when provided without any other option.
        Setting the debug level to <code class="literal">GCS_DEBUG_ALL</code>
        overrides all other options.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_communication_max_message_size"></a>
        <a class="indexterm" name="idm46444257904240"></a>

        <a class="indexterm" name="idm46444257903120"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_communication_max_message_size"><code class="literal">group_replication_communication_max_message_size</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_communication_max_message_size"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-communication-max-message-size=#</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Introduced</strong></span></td>
<td>8.0.16</td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_communication_max_message_size">group_replication_communication_max_message_size</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>Integer</td>
</tr><tr><td scope="row"><span class="bold"><strong>Default Value</strong></span></td>
<td><code class="literal">10485760</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Minimum Value</strong></span></td>
<td><code class="literal">0</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Maximum Value</strong></span></td>
<td><code class="literal">1073741824</code></td>
</tr></tbody></table>
</div>
<p>
        Specifies a maximum message size for Group Replication
        communications. Messages greater than this size are
        automatically split into fragments that are sent separately and
        reassembled by the recipients. For more information, see
        <a class="xref" href="group-replication.html#group-replication-performance-message-fragmentation" title="18.6.4 Message Fragmentation">Section 18.6.4, “Message Fragmentation”</a>.
      </p><p>
        A maximum message size of 10485760 bytes (10 MiB) is set by
        default, which means that fragmentation is used by default in
        releases from MySQL 8.0.16. The greatest permitted value is the
        same as the maximum value of the
        <a class="link" href="replication.html#sysvar_slave_max_allowed_packet"><code class="literal">slave_max_allowed_packet</code></a> system
        variable, which is 1073741824 bytes (1 GB). The setting for
        <a class="link" href="group-replication.html#sysvar_group_replication_communication_max_message_size"><code class="literal">group_replication_communication_max_message_size</code></a>
        must be less than the
        <a class="link" href="replication.html#sysvar_slave_max_allowed_packet"><code class="literal">slave_max_allowed_packet</code></a>
        setting, because the applier thread cannot handle message
        fragments larger than
        <a class="link" href="replication.html#sysvar_slave_max_allowed_packet"><code class="literal">slave_max_allowed_packet</code></a>. To
        switch off fragmentation, specify a zero value for
        <a class="link" href="group-replication.html#sysvar_group_replication_communication_max_message_size"><code class="literal">group_replication_communication_max_message_size</code></a>.
        The value of
        <a class="link" href="group-replication.html#sysvar_group_replication_communication_max_message_size"><code class="literal">group_replication_communication_max_message_size</code></a>
        should be the same on all group members.
      </p><p>
        In order for members of a replication group to use
        fragmentation, the group's communication protocol version must
        be MySQL 8.0.16 or above. Use the
        <a class="link" href="sql-statements.html#udf_group-replication-get-communication-protocol"><code class="literal">group_replication_get_communication_protocol()</code></a>
        UDF to view the group's communication protocol version. If a
        lower version is in use, group members do not fragment messages.
        You can use the
        <a class="link" href="sql-statements.html#udf_group-replication-set-communication-protocol"><code class="literal">group_replication_set_communication_protocol()</code></a>
        UDF to set the group's communication protocol to a higher
        version if all group members support it. For more information,
        see <a class="xref" href="group-replication.html#group-replication-communication-protocol" title="18.4.1.4 Setting a Group's Communication Protocol Version">Section 18.4.1.4, “Setting a Group's Communication Protocol Version”</a>.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_components_stop_timeout"></a>
        <a class="indexterm" name="idm46444257848016"></a>

        <a class="indexterm" name="idm46444257846896"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_components_stop_timeout"><code class="literal">group_replication_components_stop_timeout</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_components_stop_timeout"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-components-stop-timeout=#</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_components_stop_timeout">group_replication_components_stop_timeout</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>Integer</td>
</tr><tr><td scope="row"><span class="bold"><strong>Default Value</strong></span></td>
<td><code class="literal">31536000</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Minimum Value</strong></span></td>
<td><code class="literal">2</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Maximum Value</strong></span></td>
<td><code class="literal">31536000</code></td>
</tr></tbody></table>
</div>
<p>
        Timeout, in seconds, that Group Replication waits for each of
        the components when shutting down.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_compression_threshold"></a>
        <a class="indexterm" name="idm46444257808592"></a>

        <a class="indexterm" name="idm46444257807552"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_compression_threshold"><code class="literal">group_replication_compression_threshold</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_compression_threshold"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-compression-threshold=#</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_compression_threshold">group_replication_compression_threshold</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>Integer</td>
</tr><tr><td scope="row"><span class="bold"><strong>Default Value</strong></span></td>
<td><code class="literal">1000000</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Minimum Value</strong></span></td>
<td><code class="literal">0</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Maximum Value</strong></span></td>
<td><code class="literal">4294967295</code></td>
</tr></tbody></table>
</div>
<p>
        The threshold value in bytes above which compression is applied
        to messages sent between group members. If this system variable
        is set to zero, compression is disabled. The value of
        <a class="link" href="group-replication.html#sysvar_group_replication_compression_threshold"><code class="literal">group_replication_compression_threshold</code></a>
        should be the same on all group members.
      </p><p>
        Group Replication uses the LZ4 compression algorithm to compress
        messages sent in the group. Note that the maximum supported
        input size for the LZ4 compression algorithm is 2113929216
        bytes. This limit is lower than the maximum possible value for
        the
        <a class="link" href="group-replication.html#sysvar_group_replication_compression_threshold"><code class="literal">group_replication_compression_threshold</code></a>
        system variable, which is matched to the maximum message size
        accepted by XCom. With the LZ4 compression algorithm, do not set
        a value greater than 2113929216 bytes for
        <a class="link" href="group-replication.html#sysvar_group_replication_compression_threshold"><code class="literal">group_replication_compression_threshold</code></a>,
        because transactions above this size cannot be committed when
        message compression is enabled.
      </p><p>
        For more information, see
        <a class="xref" href="group-replication.html#group-replication-message-compression" title="18.6.3 Message Compression">Section 18.6.3, “Message Compression”</a>.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_consistency"></a>
        <a class="indexterm" name="idm46444257763088"></a>

        <a class="indexterm" name="idm46444257761984"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_consistency"><code class="literal">group_replication_consistency</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_consistency"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-consistency=value</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Introduced</strong></span></td>
<td>8.0.14</td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_consistency">group_replication_consistency</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global, Session</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>Enumeration</td>
</tr><tr><td scope="row"><span class="bold"><strong>Default Value</strong></span></td>
<td><code class="literal">EVENTUAL</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Valid Values</strong></span></td>
<td><p class="valid-value"><code class="literal">EVENTUAL</code></p><p class="valid-value"><code class="literal">BEFORE_ON_PRIMARY_FAILOVER</code></p><p class="valid-value"><code class="literal">BEFORE</code></p><p class="valid-value"><code class="literal">AFTER</code></p><p class="valid-value"><code class="literal">BEFORE_AND_AFTER</code></p></td>
</tr></tbody></table>
</div>
<p>
        Controls the transaction consistency guarantee which a group
        provides. You can configure the consistency globally or per
        transaction. Also configures the fencing mechanism used by newly
        elected primaries in single primary groups. The effect of the
        variable must be considered for both read only (RO) and read
        write (RW) transactions. The following list shows the possible
        values of this variable, in order of increasing transaction
        consistency guarantee:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
            <code class="literal">EVENTUAL</code>
          </p><p>
            Both RO and RW transactions do not wait for preceding
            transactions to be applied before executing. This was the
            behavior of Group Replication before this variable was
            added. A RW transaction does not wait for other members to
            apply a transaction. This means that a transaction could be
            externalized on one member before the others. This also
            means that in the event of a primary failover, the new
            primary can accept new RO and RW transactions before the
            previous primary transactions are all applied. RO
            transactions could result in outdated values, RW
            transactions could result in a rollback due to conflicts.
          </p></li><li class="listitem"><p>
            <code class="literal">BEFORE_ON_PRIMARY_FAILOVER</code>
          </p><p>
            New RO or RW transactions with a newly elected primary that
            is applying backlog from the old primary are held (not
            applied) until any backlog has been applied. This ensures
            that when a primary failover happens, intentionally or not,
            clients always see the latest value on the primary. This
            guarantees consistency, but means that clients must be able
            to handle the delay in the event that a backlog is being
            applied. Usually this delay should be minimal, but does
            depend on the size of the backlog.
          </p></li><li class="listitem"><p>
            <code class="literal">BEFORE</code>
          </p><p>
            A RW transaction waits for all preceding transactions to
            complete before being applied. A RO transaction waits for
            all preceding transactions to complete before being
            executed. This ensures that this transaction reads the
            latest value by only affecting the latency of the
            transaction. This reduces the overhead of synchronization on
            every RW transaction, by ensuring synchronization is used
            only on RO transactions. This consistency level also
            includes the consistency guarantees provided by
            <code class="literal">BEFORE_ON_PRIMARY_FAILOVER</code>.
          </p></li><li class="listitem"><p>
            <code class="literal">AFTER</code>
          </p><p>
            A RW transaction waits until its changes have been applied
            to all of the other members. This value has no effect on RO
            transactions. This mode ensures that when a transaction is
            committed on the local member, any subsequent transaction
            reads the written value or a more recent value on any group
            member. Use this mode with a group that is used for
            predominantly RO operations to ensure that applied RW
            transactions are applied everywhere once they commit. This
            could be used by your application to ensure that subsequent
            reads fetch the latest data which includes the latest
            writes. This reduces the overhead of synchronization on
            every RO transaction, by ensuring synchronization is used
            only on RW transactions. This consistency level also
            includes the consistency guarantees provided by
            <code class="literal">BEFORE_ON_PRIMARY_FAILOVER</code>.
          </p></li><li class="listitem"><p>
            <code class="literal">BEFORE_AND_AFTER</code>
          </p><p>
            A RW transaction waits for 1) all preceding transactions to
            complete before being applied and 2) until its changes have
            been applied on other members. A RO transaction waits for
            all preceding transactions to complete before execution
            takes place. This consistency level also includes the
            consistency guarantees provided by
            <code class="literal">BEFORE_ON_PRIMARY_FAILOVER</code>.
</p></li></ul>
</div>
<p>
        The <a class="link" href="security.html#priv_group-replication-admin"><code class="literal">GROUP_REPLICATION_ADMIN</code></a>
        privilege is required to change the global setting for this
        system variable. For more information, see
        <a class="xref" href="group-replication.html#group-replication-consistency-guarantees" title="18.4.2 Transaction Consistency Guarantees">Section 18.4.2, “Transaction Consistency Guarantees”</a>.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_enforce_update_everywhere_checks"></a>
        <a class="indexterm" name="idm46444257701152"></a>

        <a class="indexterm" name="idm46444257700112"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_enforce_update_everywhere_checks"><code class="literal">group_replication_enforce_update_everywhere_checks</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_enforce_update_everywhere_checks"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-enforce-update-everywhere-checks[={OFF|ON}]</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_enforce_update_everywhere_checks">group_replication_enforce_update_everywhere_checks</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>Boolean</td>
</tr><tr><td scope="row"><span class="bold"><strong>Default Value</strong></span></td>
<td><code class="literal">OFF</code></td>
</tr></tbody></table>
</div>
<p>
        Enable or disable strict consistency checks for multi-primary
        update everywhere. The default is that checks are disabled. In
        single-primary mode, this option must be disabled on all group
        members. In multi-primary mode, when this option is enabled,
        statements are checked as follows to ensure they are compatible
        with multi-primary mode:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
            If a transaction is executed under the
            <code class="literal">SERIALIZABLE</code> isolation level, then its
            commit fails when synchronizing itself with the group.
          </p></li><li class="listitem"><p>
            If a transaction executes against a table that has foreign
            keys with cascading constraints, then the transaction fails
            to commit when synchronizing itself with the group.
</p></li></ul>
</div>
<p>
        This system variable is a group-wide configuration setting. It
        must have the same value on all group members, cannot be changed
        while Group Replication is running, and requires a full reboot
        of the group (a bootstrap by a server with
        <a class="link" href="group-replication.html#sysvar_group_replication_bootstrap_group"><code class="literal">group_replication_bootstrap_group=ON</code></a>)
        in order for the value change to take effect. From MySQL 8.0.16,
        you can use the
        <a class="link" href="sql-statements.html#udf_group-replication-switch-to-single-primary-mode"><code class="literal">group_replication_switch_to_single_primary_mode()</code></a>
        and
        <a class="link" href="sql-statements.html#udf_group-replication-switch-to-multi-primary-mode"><code class="literal">group_replication_switch_to_multi_primary_mode()</code></a>
        UDFs to change the value of this system variable while the group
        is still running. For more information, see
        <a class="xref" href="group-replication.html#group-replication-changing-group-mode" title="18.4.1.2 Changing a Group's Mode">Section 18.4.1.2, “Changing a Group's Mode”</a>.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_exit_state_action"></a>
        <a class="indexterm" name="idm46444257658912"></a>

        <a class="indexterm" name="idm46444257657872"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_exit_state_action"><code class="literal">group_replication_exit_state_action</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_exit_state_action"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-exit-state-action=value</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Introduced</strong></span></td>
<td>8.0.12</td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_exit_state_action">group_replication_exit_state_action</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>Enumeration</td>
</tr><tr><td scope="row"><span class="bold"><strong>Default Value</strong></span> (≥ 8.0.16)</td>
<td><code class="literal">READ_ONLY</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Default Value</strong></span> (≥ 8.0.12, ≤ 8.0.15)</td>
<td><code class="literal">ABORT_SERVER</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Valid Values</strong></span> (≥ 8.0.18)</td>
<td><p class="valid-value"><code class="literal">ABORT_SERVER</code></p><p class="valid-value"><code class="literal">OFFLINE_MODE</code></p><p class="valid-value"><code class="literal">READ_ONLY</code></p></td>
</tr><tr><td scope="row"><span class="bold"><strong>Valid Values</strong></span> (≥ 8.0.12, ≤ 8.0.17)</td>
<td><p class="valid-value"><code class="literal">ABORT_SERVER</code></p><p class="valid-value"><code class="literal">READ_ONLY</code></p></td>
</tr></tbody></table>
</div>
<p>
        Configures how Group Replication behaves when a server instance
        leaves the group unintentionally, for example after encountering
        an applier error, or in the case of a loss of majority, or when
        another member of the group expels it due to a suspicion timing
        out. The timeout period for a member to leave the group in the
        case of a loss of majority is set by the
        <a class="link" href="group-replication.html#sysvar_group_replication_unreachable_majority_timeout"><code class="literal">group_replication_unreachable_majority_timeout</code></a>
        system variable, and the timeout period for suspicions is set by
        the
        <a class="link" href="group-replication.html#sysvar_group_replication_member_expel_timeout"><code class="literal">group_replication_member_expel_timeout</code></a>
        system variable. Note that an expelled group member does not
        know that it was expelled until it reconnects to the group, so
        the specified action is only taken if the member manages to
        reconnect, or if the member raises a suspicion on itself and
        expels itself.
      </p><p>
        When a member is expelled due to a suspicion timing out or a
        loss of majority, if the member has the <a class="link" href="group-replication.html#sysvar_group_replication_autorejoin_tries"><code class="literal">
        group_replication_autorejoin_tries</code></a> system variable set
        to specify a number of auto-rejoin attempts, it first makes the
        specified number of attempts while in super read only mode, and
        then follows the action specified by
        <a class="link" href="group-replication.html#sysvar_group_replication_exit_state_action"><code class="literal">group_replication_exit_state_action</code></a>.
        Auto-rejoin attempts are not made in case of an applier error,
        because these are not recoverable.
      </p><p>
        When
        <a class="link" href="group-replication.html#sysvar_group_replication_exit_state_action"><code class="literal">group_replication_exit_state_action</code></a>
        is set to <code class="literal">READ_ONLY</code>, if the member exits the
        group unintentionally or exhausts its auto-rejoin attempts, the
        instance switches MySQL to super read only mode (by setting the
        system variable <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only</code></a>
        to <code class="literal">ON</code>). The <code class="literal">READ_ONLY</code> exit
        action was the behavior for MySQL 8.0 releases before the system
        variable was introduced, and became the default again from MySQL
        8.0.16.
      </p><p>
        When
        <a class="link" href="group-replication.html#sysvar_group_replication_exit_state_action"><code class="literal">group_replication_exit_state_action</code></a>
        is set to <code class="literal">OFFLINE_MODE</code>, if the member exits
        the group unintentionally or exhausts its auto-rejoin attempts,
        the instance switches MySQL to offline mode (by setting the
        system variable <a class="link" href="server-administration.html#sysvar_offline_mode"><code class="literal">offline_mode</code></a> to
        <code class="literal">ON</code>). In this mode, connected client users are
        disconnected on their next request and connections are no longer
        accepted, with the exception of client users that have the
        <a class="link" href="security.html#priv_connection-admin"><code class="literal">CONNECTION_ADMIN</code></a> privilege (or
        the deprecated <a class="link" href="security.html#priv_super"><code class="literal">SUPER</code></a> privilege).
        Group Replication also sets the system variable
        <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only</code></a> to
        <code class="literal">ON</code>, so clients cannot make any updates, even
        if they have connected with the
        <a class="link" href="security.html#priv_connection-admin"><code class="literal">CONNECTION_ADMIN</code></a> or
        <a class="link" href="security.html#priv_super"><code class="literal">SUPER</code></a> privilege. The
        <code class="literal">OFFLINE_MODE</code> exit action is available from
        MySQL 8.0.18.
      </p><p>
        When
        <a class="link" href="group-replication.html#sysvar_group_replication_exit_state_action"><code class="literal">group_replication_exit_state_action</code></a>
        is set to <code class="literal">ABORT_SERVER</code>, if the member exits
        the group unintentionally or exhausts its auto-rejoin attempts,
        the instance shuts down MySQL. This setting was the default from
        MySQL 8.0.12, when the system variable was added, to MySQL
        8.0.15 inclusive.
</p>
<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Important
</div>
<p>
          If a failure occurs before the member has successfully joined
          the group, the specified exit action <span class="emphasis"><em>is not
          taken</em></span>. This is the case if there is a failure
          during the local configuration check, or a mismatch between
          the configuration of the joining member and the configuration
          of the group. In these situations, the
          <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only</code></a> system
          variable is left with its original value, connections continue
          to be accepted, and the server does not shut down MySQL. To
          ensure that the server cannot accept updates when Group
          Replication did not start, we therefore recommend that
          <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only=ON</code></a> is set in
          the server's configuration file at startup, which Group
          Replication will change to <code class="literal">OFF</code> on primary
          members after it has been started successfully. This safeguard
          is particularly important when the server is configured to
          start Group Replication on server boot
          (<a class="link" href="group-replication.html#sysvar_group_replication_start_on_boot"><code class="literal">group_replication_start_on_boot=ON</code></a>),
          but it is also useful when Group Replication is started
          manually using a <a class="link" href="sql-statements.html#start-group-replication" title="13.4.3.1 START GROUP_REPLICATION Statement"><code class="literal">START
          GROUP_REPLICATION</code></a> command.
</p>
</div>
<p>
        For more information on using this option, and the full list of
        situations in which the exit action is taken, see
        <a class="xref" href="group-replication.html#group-replication-responses-failure-exit" title="18.6.6.4 Exit Action">Section 18.6.6.4, “Exit Action”</a>.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_flow_control_applier_threshold"></a>
        <a class="indexterm" name="idm46444257572672"></a>

        <a class="indexterm" name="idm46444257571552"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_flow_control_applier_threshold"><code class="literal">group_replication_flow_control_applier_threshold</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_flow_control_applier_threshold"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-flow-control-applier-threshold=#</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_flow_control_applier_threshold">group_replication_flow_control_applier_threshold</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>Integer</td>
</tr><tr><td scope="row"><span class="bold"><strong>Default Value</strong></span></td>
<td><code class="literal">25000</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Minimum Value</strong></span></td>
<td><code class="literal">0</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Maximum Value</strong></span></td>
<td><code class="literal">2147483647</code></td>
</tr></tbody></table>
</div>
<p>
        Specifies the number of waiting transactions in the applier
        queue that trigger flow control. This variable can be changed
        without resetting Group Replication.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_flow_control_certifier_threshold"></a>
        <a class="indexterm" name="idm46444257533136"></a>

        <a class="indexterm" name="idm46444257532096"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_flow_control_certifier_threshold"><code class="literal">group_replication_flow_control_certifier_threshold</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_flow_control_certifier_threshold"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-flow-control-certifier-threshold=#</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_flow_control_certifier_threshold">group_replication_flow_control_certifier_threshold</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>Integer</td>
</tr><tr><td scope="row"><span class="bold"><strong>Default Value</strong></span></td>
<td><code class="literal">25000</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Minimum Value</strong></span></td>
<td><code class="literal">0</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Maximum Value</strong></span></td>
<td><code class="literal">2147483647</code></td>
</tr></tbody></table>
</div>
<p>
        Specifies the number of waiting transactions in the certifier
        queue that trigger flow control. This variable can be changed
        without resetting Group Replication.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_flow_control_hold_percent"></a>
        <a class="indexterm" name="idm46444257493520"></a>

        <a class="indexterm" name="idm46444257492480"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_flow_control_hold_percent"><code class="literal">group_replication_flow_control_hold_percent</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_flow_control_hold_percent"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-flow-control-hold-percent=#</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_flow_control_hold_percent">group_replication_flow_control_hold_percent</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>Integer</td>
</tr><tr><td scope="row"><span class="bold"><strong>Default Value</strong></span></td>
<td><code class="literal">10</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Minimum Value</strong></span></td>
<td><code class="literal">0</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Maximum Value</strong></span></td>
<td><code class="literal">100</code></td>
</tr></tbody></table>
</div>
<p>
        Defines what percentage of the group quota remains unused to
        allow a cluster under flow control to catch up on backlog. A
        value of 0 implies that no part of the quota is reserved for
        catching up on the work backlog.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_flow_control_max_commit_quota"></a>
        <a class="indexterm" name="idm46444257454112"></a>

        <a class="indexterm" name="idm46444257452992"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_flow_control_max_commit_quota"><code class="literal">group_replication_flow_control_max_commit_quota</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_flow_control_max_commit_quota"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-flow-control-max-commit-quota=#</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_flow_control_max_commit_quota">group_replication_flow_control_max_commit_quota</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>Integer</td>
</tr><tr><td scope="row"><span class="bold"><strong>Default Value</strong></span></td>
<td><code class="literal">0</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Minimum Value</strong></span></td>
<td><code class="literal">0</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Maximum Value</strong></span></td>
<td><code class="literal">2147483647</code></td>
</tr></tbody></table>
</div>
<p>
        Defines the maximum flow control quota of the group, or the
        maximum available quota for any period while flow control is
        enabled. A value of 0 implies that there is no maximum quota
        set. Cannot be smaller than
        <a class="link" href="group-replication.html#sysvar_group_replication_flow_control_min_quota"><code class="literal">group_replication_flow_control_min_quota</code></a>
        and
        <code class="literal">group_replication_flow_control_min_recovery_quota</code>.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_flow_control_member_quota_percent"></a>
        <a class="indexterm" name="idm46444257412464"></a>

        <a class="indexterm" name="idm46444257411424"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_flow_control_member_quota_percent"><code class="literal">group_replication_flow_control_member_quota_percent</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_flow_control_member_quota_percent"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-flow-control-member-quota-percent=#</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_flow_control_member_quota_percent">group_replication_flow_control_member_quota_percent</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>Integer</td>
</tr><tr><td scope="row"><span class="bold"><strong>Default Value</strong></span></td>
<td><code class="literal">0</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Minimum Value</strong></span></td>
<td><code class="literal">0</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Maximum Value</strong></span></td>
<td><code class="literal">100</code></td>
</tr></tbody></table>
</div>
<p>
        Defines the percentage of the quota that a member should assume
        is available for itself when calculating the quotas. A value of
        0 implies that the quota should be split equally between members
        that were writers in the last period.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_flow_control_min_quota"></a>
        <a class="indexterm" name="idm46444257372832"></a>

        <a class="indexterm" name="idm46444257371792"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_flow_control_min_quota"><code class="literal">group_replication_flow_control_min_quota</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_flow_control_min_quota"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-flow-control-min-quota=#</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_flow_control_min_quota">group_replication_flow_control_min_quota</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>Integer</td>
</tr><tr><td scope="row"><span class="bold"><strong>Default Value</strong></span></td>
<td><code class="literal">0</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Minimum Value</strong></span></td>
<td><code class="literal">0</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Maximum Value</strong></span></td>
<td><code class="literal">2147483647</code></td>
</tr></tbody></table>
</div>
<p>
        Controls the lowest flow control quota that can be assigned to a
        member, independently of the calculated minimum quota executed
        in the last period. A value of 0 implies that there is no
        minimum quota. Cannot be larger than
        <a class="link" href="group-replication.html#sysvar_group_replication_flow_control_max_commit_quota"><code class="literal">group_replication_flow_control_max_commit_quota</code></a>.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_flow_control_min_recovery_quota"></a>
        <a class="indexterm" name="idm46444257331952"></a>

        <a class="indexterm" name="idm46444257330912"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_flow_control_min_recovery_quota"><code class="literal">group_replication_flow_control_min_recovery_quota</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_flow_control_min_recovery_quota"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-flow-control-min-recovery-quota=#</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_flow_control_min_recovery_quota">group_replication_flow_control_min_recovery_quota</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>Integer</td>
</tr><tr><td scope="row"><span class="bold"><strong>Default Value</strong></span></td>
<td><code class="literal">0</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Minimum Value</strong></span></td>
<td><code class="literal">0</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Maximum Value</strong></span></td>
<td><code class="literal">2147483647</code></td>
</tr></tbody></table>
</div>
<p>
        Controls the lowest quota that can be assigned to a member
        because of another recovering member in the group, independently
        of the calculated minimum quota executed in the last period. A
        value of 0 implies that there is no minimum quota. Cannot be
        larger than
        <code class="literal">group_replication_flow_control_max_commit_quota</code>.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_flow_control_mode"></a>
        <a class="indexterm" name="idm46444257291504"></a>

        <a class="indexterm" name="idm46444257290464"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_flow_control_mode"><code class="literal">group_replication_flow_control_mode</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_flow_control_mode"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-flow-control-mode=value</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_flow_control_mode">group_replication_flow_control_mode</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>Enumeration</td>
</tr><tr><td scope="row"><span class="bold"><strong>Default Value</strong></span></td>
<td><code class="literal">QUOTA</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Valid Values</strong></span></td>
<td><p class="valid-value"><code class="literal">DISABLED</code></p><p class="valid-value"><code class="literal">QUOTA</code></p></td>
</tr></tbody></table>
</div>
<p>
        Specifies the mode used for flow control. This variable can be
        changed without resetting Group Replication.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_flow_control_period"></a>
        <a class="indexterm" name="idm46444257253856"></a>

        <a class="indexterm" name="idm46444257252816"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_flow_control_period"><code class="literal">group_replication_flow_control_period</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_flow_control_period"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-flow-control-period=#</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_flow_control_period">group_replication_flow_control_period</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>Integer</td>
</tr><tr><td scope="row"><span class="bold"><strong>Default Value</strong></span></td>
<td><code class="literal">1</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Minimum Value</strong></span></td>
<td><code class="literal">1</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Maximum Value</strong></span></td>
<td><code class="literal">60</code></td>
</tr></tbody></table>
</div>
<p>
        Defines how many seconds to wait between flow control
        iterations, in which flow control messages are sent and flow
        control management tasks are run.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_flow_control_release_percent"></a>
        <a class="indexterm" name="idm46444257214528"></a>

        <a class="indexterm" name="idm46444257213488"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_flow_control_release_percent"><code class="literal">group_replication_flow_control_release_percent</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_flow_control_release_percent"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-flow-control-release-percent=#</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_flow_control_release_percent">group_replication_flow_control_release_percent</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>Integer</td>
</tr><tr><td scope="row"><span class="bold"><strong>Default Value</strong></span></td>
<td><code class="literal">50</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Minimum Value</strong></span></td>
<td><code class="literal">0</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Maximum Value</strong></span></td>
<td><code class="literal">1000</code></td>
</tr></tbody></table>
</div>
<p>
        Defines how the group quota should be released when flow control
        no longer needs to throttle the writer members, with this
        percentage being the quota increase per flow control period. A
        value of 0 implies that once the flow control thresholds are
        within limits the quota is released in a single flow control
        iteration. The range allows the quota to be released at up to 10
        times current quota, as that allows a greater degree of
        adaptation, mainly when the flow control period is large and the
        quotas are very small.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_force_members"></a>
        <a class="indexterm" name="idm46444257174192"></a>

        <a class="indexterm" name="idm46444257173088"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_force_members"><code class="literal">group_replication_force_members</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_force_members"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-force-members=value</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_force_members">group_replication_force_members</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>String</td>
</tr></tbody></table>
</div>
<p>
        A list of peer addresses as a comma separated list such as
        <code class="literal">host1:port1</code>,<code class="literal">host2:port2</code>.
        This option is used to force a new group membership, in which
        the excluded members do not receive a new view and are blocked.
      </p><p>
        You must specify the address or host name and port as they are
        given in the
        <a class="link" href="group-replication.html#sysvar_group_replication_local_address"><code class="literal">group_replication_local_address</code></a>
        option for each member. An IPv6 address must be specified in
        square brackets. For example:
      </p><pre data-lang="simple" class="programlisting">"198.51.100.44:33061,[2001:db8:85a3:8d3:1319:8a2e:370:7348]:33061,example.org:33061"</pre><p>
        The group communication engine for Group Replication (XCom)
        checks that the supplied IP addresses are in a valid format, and
        checks that you have not included any group members that are
        currently unreachable. Otherwise, the new configuration is not
        validated, so you must be careful to include only online servers
        that are reachable members of the group. Any incorrect values or
        invalid host names in the list could cause the group to be
        blocked with an invalid configuration.
      </p><p>
        It is important before forcing a new membership configuration to
        ensure that the servers to be excluded have been shut down. If
        they are not, shut them down before proceeding. Group members
        that are still online can automatically form new configurations,
        and if this has already taken place, forcing a further new
        configuration could create an artificial split-brain situation
        for the group.
      </p><p>
        After you have used the
        <a class="link" href="group-replication.html#sysvar_group_replication_force_members"><code class="literal">group_replication_force_members</code></a>
        system variable to successfully force a new group membership and
        unblock the group, ensure that you clear the system variable.
        <a class="link" href="group-replication.html#sysvar_group_replication_force_members"><code class="literal">group_replication_force_members</code></a>
        must be empty in order to issue a <a class="link" href="sql-statements.html#start-group-replication" title="13.4.3.1 START GROUP_REPLICATION Statement"><code class="literal">START
        GROUP_REPLICATION</code></a> statement.
      </p><p>
        For details of the procedure to follow, see
        <a class="xref" href="group-replication.html#group-replication-network-partitioning" title="18.4.4 Network Partitioning">Section 18.4.4, “Network Partitioning”</a>.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_group_name"></a>
        <a class="indexterm" name="idm46444257131952"></a>

        <a class="indexterm" name="idm46444257130848"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_group_name"><code class="literal">group_replication_group_name</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_group_name"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-group-name=value</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_group_name">group_replication_group_name</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>String</td>
</tr></tbody></table>
</div>
<p>
        The name of the group which this server instance belongs to.
        Must be a valid UUID. This UUID is used internally when setting
        GTIDs for Group Replication events in the binary log.
</p>
<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Important
</div>
<p>
          A unique UUID must be used.
</p>
</div>
</li><li class="listitem"><p><a name="sysvar_group_replication_group_seeds"></a>
        <a class="indexterm" name="idm46444257101040"></a>

        <a class="indexterm" name="idm46444257099936"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_group_seeds"><code class="literal">group_replication_group_seeds</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_group_seeds"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-group-seeds=value</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_group_seeds">group_replication_group_seeds</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>String</td>
</tr></tbody></table>
</div>
<p>
        A list of group members that provide a member which joins the
        group with the data required for the joining member to gain
        synchrony with the group. The list consists of a single internal
        network address or host name for each included seed member, as
        configured in the seed member's
        <a class="link" href="group-replication.html#sysvar_group_replication_local_address"><code class="literal">group_replication_local_address</code></a>
        system variable (not the seed member's SQL hostname and port).
        The addresses of the seed members are specified as a comma
        separated list, such as
        <code class="literal">host1:port1</code>,<code class="literal">host2:port2</code>.
        An IPv6 address must be specified in square brackets. For
        example:
      </p><pre data-lang="simple" class="programlisting">group_replication_group_seeds= "198.51.100.44:33061,[2001:db8:85a3:8d3:1319:8a2e:370:7348]:33061, example.org:33061"</pre><p>
        Note that the value you specify for this variable is not
        validated until a <a class="link" href="sql-statements.html#start-group-replication" title="13.4.3.1 START GROUP_REPLICATION Statement"><code class="literal">START
        GROUP_REPLICATION</code></a> statement is issued and the Group
        Communication System (GCS) is available.
      </p><p>
        Usually this list consists of all members of the group, but you
        can choose a subset of the group members to be seeds. The list
        must contain at least one valid member address. Each address is
        validated when starting Group Replication. If the list does not
        contain any valid member addresses, issuing
        <a class="link" href="sql-statements.html#start-group-replication" title="13.4.3.1 START GROUP_REPLICATION Statement"><code class="literal">START GROUP_REPLICATION</code></a> fails.
      </p><p>
        When a server is joining a replication group, it attempts to
        connect to the first seed member listed in its
        <a class="link" href="group-replication.html#sysvar_group_replication_group_seeds"><code class="literal">group_replication_group_seeds</code></a>
        system variable. If the connection is refused, the joining
        member tries to connect to each of the other seed members in the
        list in order. If the joining member connects to a seed member
        but does not get added to the replication group as a result (for
        example, because the seed member does not have the joining
        member's address in its whitelist and closes the connection),
        the joining member continues to try the remaining seed members
        in the list in order.
      </p><p>
        A joining member must communicate with the seed member using the
        same protocol (IPv4 or IPv6) that the seed member advertises in
        the
        <a class="link" href="group-replication.html#sysvar_group_replication_group_seeds"><code class="literal">group_replication_group_seeds</code></a>
        option. For the purpose of IP address whitelisting for Group
        Replication, the whitelist on the seed member must include an IP
        address for the joining member for the protocol offered by the
        seed member, or a host name that resolves to an address for that
        protocol. This address or host name must be set up and
        whitelisted in addition to the joining member's
        <a class="link" href="group-replication.html#sysvar_group_replication_local_address"><code class="literal">group_replication_local_address</code></a>
        if the protocol for that address does not match the seed
        member's advertised protocol. If a joining member does not have
        a whitelisted address for the appropriate protocol, its
        connection attempt is refused. For more information, see
        <a class="xref" href="group-replication.html#group-replication-ip-address-whitelisting" title="18.5.1 Group Replication IP Address Whitelisting">Section 18.5.1, “Group Replication IP Address Whitelisting”</a>.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_gtid_assignment_block_size"></a>
        <a class="indexterm" name="idm46444257056096"></a>

        <a class="indexterm" name="idm46444257054976"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_gtid_assignment_block_size"><code class="literal">group_replication_gtid_assignment_block_size</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_gtid_assignment_block_size"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-gtid-assignment-block-size=#</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_gtid_assignment_block_size">group_replication_gtid_assignment_block_size</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>Integer</td>
</tr><tr><td scope="row"><span class="bold"><strong>Default Value</strong></span></td>
<td><code class="literal">1000000</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Minimum Value</strong></span></td>
<td><code class="literal">1</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Maximum Value</strong></span> (64-bit platforms)</td>
<td><code class="literal">9223372036854775807</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Maximum Value</strong></span> (32-bit platforms)</td>
<td><code class="literal">4294967295</code></td>
</tr></tbody></table>
</div>
<p>
        The number of consecutive GTIDs that are reserved for each
        member. Each member consumes its blocks and reserves more when
        needed.
      </p><p>
        This system variable is a group-wide configuration setting. It
        must have the same value on all group members, cannot be changed
        while Group Replication is running, and requires a full reboot
        of the group (a bootstrap by a server with
        <a class="link" href="group-replication.html#sysvar_group_replication_bootstrap_group"><code class="literal">group_replication_bootstrap_group=ON</code></a>)
        in order for the value change to take effect.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_ip_whitelist"></a>
        <a class="indexterm" name="idm46444257011248"></a>

        <a class="indexterm" name="idm46444257010208"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_ip_whitelist"><code class="literal">group_replication_ip_whitelist</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_ip_whitelist"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-ip-whitelist=value</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_ip_whitelist">group_replication_ip_whitelist</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>String</td>
</tr><tr><td scope="row"><span class="bold"><strong>Default Value</strong></span></td>
<td><code class="literal">AUTOMATIC</code></td>
</tr></tbody></table>
</div>
<p>
        Specifies which hosts are permitted to connect to the group. The
        address that you specify for each group member in
        <a class="link" href="group-replication.html#sysvar_group_replication_local_address"><code class="literal">group_replication_local_address</code></a>
        must be whitelisted on the other servers in the replication
        group. Note that the value you specify for this variable is not
        validated until a <a class="link" href="sql-statements.html#start-group-replication" title="13.4.3.1 START GROUP_REPLICATION Statement"><code class="literal">START
        GROUP_REPLICATION</code></a> statement is issued and the Group
        Communication System (GCS) is available.
      </p><p>
        By default, this system variable is set to
        <code class="literal">AUTOMATIC</code>, which permits connections from
        private subnetworks active on the host. The group communication
        engine for Group Replication (XCom) automatically scans active
        interfaces on the host, and identifies those with addresses on
        private subnetworks. These addresses and the
        <code class="literal">localhost</code> IP address for IPv4 and (from MySQL
        8.0.14) IPv6 are used to create the Group Replication whitelist.
        For a list of the ranges from which addresses are automatically
        whitelisted, see
        <a class="xref" href="group-replication.html#group-replication-ip-address-whitelisting" title="18.5.1 Group Replication IP Address Whitelisting">Section 18.5.1, “Group Replication IP Address Whitelisting”</a>.
      </p><p>
        The automatic whitelist of private addresses cannot be used for
        connections from servers outside the private network. For Group
        Replication connections between server instances that are on
        different machines, you must provide public IP addresses and
        specify these as an explicit whitelist. If you specify any
        entries for the whitelist, the private and
        <code class="literal">localhost</code> addresses are not added
        automatically, so if you use any of these, you must specify them
        explicitly.
      </p><p>
        As the value of the
        <a class="link" href="group-replication.html#sysvar_group_replication_ip_whitelist"><code class="literal">group_replication_ip_whitelist</code></a>
        option, you can specify any combination of the following:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
            IPv4 addresses (for example,
            <code class="literal">198.51.100.44</code>)
          </p></li><li class="listitem"><p>
            IPv4 addresses with CIDR notation (for example,
            <code class="literal">192.0.2.21/24</code>)
          </p></li><li class="listitem"><p>
            IPv6 addresses, from MySQL 8.0.14 (for example,
            <code class="literal">2001:db8:85a3:8d3:1319:8a2e:370:7348</code>)
          </p></li><li class="listitem"><p>
            IPv6 addresses with CIDR notation, from MySQL 8.0.14 (for
            example, <code class="literal">2001:db8:85a3:8d3::/64</code>)
          </p></li><li class="listitem"><p>
            Host names (for example, <code class="literal">example.org</code>)
          </p></li><li class="listitem"><p>
            Host names with CIDR notation (for example,
            <code class="literal">www.example.com/24</code>)
</p></li></ul>
</div>
<p>
        Before MySQL 8.0.14, host names could only resolve to IPv4
        addresses. From MySQL 8.0.14, host names can resolve to IPv4
        addresses, IPv6 addresses, or both. If a host name resolves to
        both an IPv4 and an IPv6 address, the IPv4 address is always
        used for Group Replication connections. You can use CIDR
        notation in combination with host names or IP addresses to
        whitelist a block of IP addresses with a particular network
        prefix, but do ensure that all the IP addresses in the specified
        subnet are under your control.
      </p><p>
        A comma must separate each entry in the whitelist. For example:
      </p><pre data-lang="none" class="programlisting">"192.0.2.21/24,198.51.100.44,203.0.113.0/24,2001:db8:85a3:8d3:1319:8a2e:370:7348,example.org,www.example.com/24"</pre><p>
        If any of the seed members for the group are listed in the
        <a class="link" href="group-replication.html#sysvar_group_replication_group_seeds"><code class="literal">group_replication_group_seeds</code></a>
        option with an IPv6 address when a joining member has an IPv4
        <a class="link" href="group-replication.html#sysvar_group_replication_local_address"><code class="literal">group_replication_local_address</code></a>,
        or the reverse, you must also set up and whitelist an
        alternative address for the joining member for the protocol
        offered by the seed member (or a host name that resolves to an
        address for that protocol). For more information, see
        <a class="xref" href="group-replication.html#group-replication-ip-address-whitelisting" title="18.5.1 Group Replication IP Address Whitelisting">Section 18.5.1, “Group Replication IP Address Whitelisting”</a>.
      </p><p>
        It is possible to configure different whitelists on different
        group members according to your security requirements, for
        example, in order to keep different subnets separate. However,
        this can cause issues when a group is reconfigured. If you do
        not have a specific security requirement to do otherwise, use
        the same whitelist on all members of a group. For more details,
        see <a class="xref" href="group-replication.html#group-replication-ip-address-whitelisting" title="18.5.1 Group Replication IP Address Whitelisting">Section 18.5.1, “Group Replication IP Address Whitelisting”</a>.
      </p><p>
        For host names, name resolution takes place only when a
        connection request is made by another server. A host name that
        cannot be resolved is not considered for whitelist validation,
        and a warning message is written to the error log.
        Forward-confirmed reverse DNS (FCrDNS) verification is carried
        out for resolved host names.
</p>
<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Warning
</div>
<p>
          Host names are inherently less secure than IP addresses in a
          whitelist. FCrDNS verification provides a good level of
          protection, but can be compromised by certain types of attack.
          Specify host names in your whitelist only when strictly
          necessary, and ensure that all components used for name
          resolution, such as DNS servers, are maintained under your
          control. You can also implement name resolution locally using
          the hosts file, to avoid the use of external components.
</p>
</div>
</li><li class="listitem"><p><a name="sysvar_group_replication_local_address"></a>
        <a class="indexterm" name="idm46444256948656"></a>

        <a class="indexterm" name="idm46444256947552"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_local_address"><code class="literal">group_replication_local_address</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_local_address"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-local-address=value</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_local_address">group_replication_local_address</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>String</td>
</tr></tbody></table>
</div>
<p>
        The network address which the member provides for connections
        from other members, specified as a <code class="literal">host:port</code>
        formatted string. This address must be reachable by all members
        of the group because it is used by the group communication
        engine for Group Replication (XCom, a Paxos variant) for TCP
        communication between remote XCom instances. Communication with
        the local instance is over an input channel using shared memory.
</p>
<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Warning
</div>
<p>
          Do not use this address for communication with the member.
          This is not the MySQL server SQL protocol host and port.
</p>
</div>
<p>
        The address or host name that you specify in
        <a class="link" href="group-replication.html#sysvar_group_replication_local_address"><code class="literal">group_replication_local_address</code></a>
        is used by Group Replication as the unique identifier for a
        group member within the replication group. You can use the same
        port for all members of a replication group as long as the host
        names or IP addresses are all different, and you can use the
        same host name or IP address for all members as long as the
        ports are all different. The recommended port for
        <a class="link" href="group-replication.html#sysvar_group_replication_local_address"><code class="literal">group_replication_local_address</code></a>
        is 33061. Note that the value you specify for this variable is
        not validated until the <a class="link" href="sql-statements.html#start-group-replication" title="13.4.3.1 START GROUP_REPLICATION Statement"><code class="literal">START
        GROUP_REPLICATION</code></a> statement is issued and the Group
        Communication System (GCS) is available.
      </p><p>
        The network address configured by
        <a class="link" href="group-replication.html#sysvar_group_replication_local_address"><code class="literal">group_replication_local_address</code></a>
        must be resolvable by all group members. For example, if each
        server instance is on a different machine with a fixed network
        address, you could use the IP address of the machine, such as
        10.0.0.1. If you use a host name, you must use a fully qualified
        name, and ensure it is resolvable through DNS, correctly
        configured <code class="literal">/etc/hosts</code> files, or other name
        resolution processes. From MySQL 8.0.14, IPv6 addresses (or host
        names that resolve to them) can be used as well as IPv4
        addresses. An IPv6 address must be specified in square brackets
        in order to distinguish the port number, for example:
      </p><pre data-lang="simple" class="programlisting">group_replication_local_address= "[2001:db8:85a3:8d3:1319:8a2e:370:7348]:33061"</pre><p>
        If a host name specified as the Group Replication local address
        for a server instance resolves to both an IPv4 and an IPv6
        address, the IPv4 address is always used for Group Replication
        connections. For more information on Group Replication support
        for IPv6 networks and on replication groups with a mix of
        members using IPv4 and members using IPv6, see
        <a class="xref" href="group-replication.html#group-replication-ipv6" title="18.4.5 Support For IPv6 And For Mixed IPv6 And IPv4 Groups">Section 18.4.5, “Support For IPv6 And For Mixed IPv6 And IPv4 Groups”</a>.
      </p><p>
        For the purpose of IP address whitelisting for Group
        Replication, the address that you specify for each group member
        in
        <a class="link" href="group-replication.html#sysvar_group_replication_local_address"><code class="literal">group_replication_local_address</code></a>
        must be added to the list for the
        <a class="link" href="group-replication.html#sysvar_group_replication_ip_whitelist"><code class="literal">group_replication_ip_whitelist</code></a>
        option on the other servers in the replication group. If any of
        the seed members for the group are listed in the
        <a class="link" href="group-replication.html#sysvar_group_replication_group_seeds"><code class="literal">group_replication_group_seeds</code></a>
        option with an IPv6 address when this member has an IPv4
        <a class="link" href="group-replication.html#sysvar_group_replication_local_address"><code class="literal">group_replication_local_address</code></a>,
        or the reverse, you must also set up and whitelist an
        alternative address for this member for the required protocol
        (or a host name that resolves to an address for that protocol).
        For more information, see
        <a class="xref" href="group-replication.html#group-replication-ip-address-whitelisting" title="18.5.1 Group Replication IP Address Whitelisting">Section 18.5.1, “Group Replication IP Address Whitelisting”</a>.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_member_weight"></a>
        <a class="indexterm" name="idm46444256899280"></a>

        <a class="indexterm" name="idm46444256898176"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_member_weight"><code class="literal">group_replication_member_weight</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_member_weight"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-member-weight=#</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_member_weight">group_replication_member_weight</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>Integer</td>
</tr><tr><td scope="row"><span class="bold"><strong>Default Value</strong></span></td>
<td><code class="literal">50</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Minimum Value</strong></span></td>
<td><code class="literal">0</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Maximum Value</strong></span></td>
<td><code class="literal">100</code></td>
</tr></tbody></table>
</div>
<p>
        A percentage weight that can be assigned to members to influence
        the chance of the member being elected as primary in the event
        of failover, for example when the existing primary leaves a
        single-primary group. Assign numeric weights to members to
        ensure that specific members are elected, for example during
        scheduled maintenance of the primary or to ensure certain
        hardware is prioritized in the event of failover.
      </p><p>
        For a group with members configured as follows:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
            <code class="literal">member-1</code>:
            group_replication_member_weight=30, server_uuid=aaaa
          </p></li><li class="listitem"><p>
            <code class="literal">member-2</code>:
            group_replication_member_weight=40, server_uuid=bbbb
          </p></li><li class="listitem"><p>
            <code class="literal">member-3</code>:
            group_replication_member_weight=40, server_uuid=cccc
          </p></li><li class="listitem"><p>
            <code class="literal">member-4</code>:
            group_replication_member_weight=40, server_uuid=dddd
</p></li></ul>
</div>
<p>
        during election of a new primary the members above would be
        sorted as <code class="literal">member-2</code>,
        <code class="literal">member-3</code>, <code class="literal">member-4</code>, and
        <code class="literal">member-1</code>. This results in
        <code class="literal">member</code>-2 being chosen as the new primary in
        the event of failover. For more information, see
        <a class="xref" href="group-replication.html#group-replication-single-primary-mode" title="18.1.3.1 Single-Primary Mode">Section 18.1.3.1, “Single-Primary Mode”</a>.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_member_expel_timeout"></a>
        <a class="indexterm" name="idm46444256847696"></a>

        <a class="indexterm" name="idm46444256846656"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_member_expel_timeout"><code class="literal">group_replication_member_expel_timeout</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_member_expel_timeout"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-member-expel-timeout=#</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Introduced</strong></span></td>
<td>8.0.13</td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_member_expel_timeout">group_replication_member_expel_timeout</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>Integer</td>
</tr><tr><td scope="row"><span class="bold"><strong>Default Value</strong></span></td>
<td><code class="literal">0</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Minimum Value</strong></span></td>
<td><code class="literal">0</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Maximum Value</strong></span> (≥ 8.0.14)</td>
<td><code class="literal">3600</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Maximum Value</strong></span> (≤ 8.0.13)</td>
<td><code class="literal">31536000</code></td>
</tr></tbody></table>
</div>
<p>
        The period of time in seconds that a Group Replication group
        member waits after creating a suspicion before expelling from
        the group the member suspected of having failed. The initial
        5-second detection period before a suspicion is created does not
        count as part of this time. Changing the value of
        <a class="link" href="group-replication.html#sysvar_group_replication_member_expel_timeout"><code class="literal">group_replication_member_expel_timeout</code></a>
        on a group member takes effect immediately for existing as well
        as future suspicions on that group member. It is not mandatory
        for all members of a group to have the same setting, but it is
        recommended in order to avoid unexpected expulsions.
      </p><p>
        By default,
        <a class="link" href="group-replication.html#sysvar_group_replication_member_expel_timeout"><code class="literal">group_replication_member_expel_timeout</code></a>
        is set to 0, meaning that there is no waiting period and a
        suspected member is liable for expulsion immediately after the
        5-second detection period ends. To avoid unnecessary expulsions
        on slower networks, or in the case of expected transient network
        failures or machine slowdowns, you can specify a timeout value
        greater than zero, up to a maximum of 3600 seconds (1 hour). If
        a suspect member becomes active again before the suspicion times
        out, it rejoins the group, applies all the messages that were
        buffered by the remaining group members, and enters
        <code class="literal">ONLINE</code> state.
      </p><p>
        If the timeout is exceeded, the suspect member is liable for
        expulsion immediately after the suspicion times out. If the
        member is able to resume communications and receives a view
        where it is expelled, and the member has the
        <a class="link" href="group-replication.html#sysvar_group_replication_autorejoin_tries"><code class="literal">group_replication_autorejoin_tries</code></a>
        system variable set to specify a number of auto-rejoin attempts,
        it proceeds to make the specified number of attempts to rejoin
        the group while in super read only mode. If the member does not
        have any auto-rejoin attempts specified, or if it has exhausted
        the specified number of attempts, it follows the action
        specified by the system variable
        <a class="link" href="group-replication.html#sysvar_group_replication_exit_state_action"><code class="literal">group_replication_exit_state_action</code></a>.
      </p><p>
        For more information on using this option, see
        <a class="xref" href="group-replication.html#group-replication-responses-failure-expel" title="18.6.6.1 Expel Timeout">Section 18.6.6.1, “Expel Timeout”</a>. For
        alternative mitigation strategies to avoid unnecessary
        expulsions where this system variable is not available, see
        <a class="xref" href="group-replication.html#group-replication-limitations" title="18.9.2 Group Replication Limitations">Section 18.9.2, “Group Replication Limitations”</a>.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_message_cache_size"></a>
        <a class="indexterm" name="idm46444256791520"></a>

        <a class="indexterm" name="idm46444256790480"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_message_cache_size"><code class="literal">group_replication_message_cache_size</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_message_cache_size"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-message-cache-size=#</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Introduced</strong></span></td>
<td>8.0.16</td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_message_cache_size">group_replication_message_cache_size</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>Integer</td>
</tr><tr><td scope="row"><span class="bold"><strong>Default Value</strong></span></td>
<td><code class="literal">1073741824 (1 GB)</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Minimum Value</strong></span></td>
<td><code class="literal">1073741824 (1 GB)</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Maximum Value</strong></span> (64-bit platforms)</td>
<td><code class="literal">18446744073709551615 (16 EiB)</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Maximum Value</strong></span> (32-bit platforms)</td>
<td><code class="literal">315360004294967295 (4 GB)</code></td>
</tr></tbody></table>
</div>
<p>
        The maximum amount of memory that is available for the message
        cache in the group communication engine for Group Replication
        (XCom), which holds messages (and their metadata) that are
        exchanged between the group members as a part of the consensus
        protocol. Among other functions, the message cache is used for
        recovery by members that return to the group after a period
        where they were unable to communicate with the other group
        members. The
        <a class="link" href="group-replication.html#sysvar_group_replication_member_expel_timeout"><code class="literal">group_replication_member_expel_timeout</code></a>
        system variable determines the time (up to an hour) allowed for
        members to return to the group rather than being expelled. The
        size of the message cache should be set with reference to the
        expected volume of messages in this time period, so that it
        contains all the missed messages required for members to return
        successfully.
      </p><p>
        <a class="link" href="group-replication.html#sysvar_group_replication_message_cache_size"><code class="literal">group_replication_message_cache_size</code></a>
        has a default and minimum setting of 1073741824 bytes (1 GB).
        The same cache size limit should be set on all group members,
        because an unreachable member that is attempting to reconnect
        selects any other member at random for recovery of missed
        messages. Ensure that sufficient memory is available on your
        system for your chosen cache size limit, considering the size of
        MySQL Server's other caches and object pools.
      </p><p>
        The cache size limit can be increased or reduced dynamically at
        runtime. If you reduce the cache size limit, XCom removes the
        oldest entries that have been decided and delivered until the
        current size is below the limit. Group Replication's Group
        Communication System (GCS) alerts you, by a warning message,
        when a message that is likely to be needed for recovery by a
        member that is currently unreachable is removed from the message
        cache. For more information on tuning the message cache size,
        see <a class="xref" href="group-replication.html#group-replication-performance-xcom-cache" title="18.6.5 XCom Cache Management">Section 18.6.5, “XCom Cache Management”</a>.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_poll_spin_loops"></a>
        <a class="indexterm" name="idm46444256739936"></a>

        <a class="indexterm" name="idm46444256738896"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_poll_spin_loops"><code class="literal">group_replication_poll_spin_loops</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_poll_spin_loops"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-poll-spin-loops=#</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_poll_spin_loops">group_replication_poll_spin_loops</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>Integer</td>
</tr><tr><td scope="row"><span class="bold"><strong>Default Value</strong></span></td>
<td><code class="literal">0</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Minimum Value</strong></span></td>
<td><code class="literal">0</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Maximum Value</strong></span> (64-bit platforms)</td>
<td><code class="literal">18446744073709551615</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Maximum Value</strong></span> (32-bit platforms)</td>
<td><code class="literal">4294967295</code></td>
</tr></tbody></table>
</div>
<p>
        The number of times the group communication thread waits for the
        communication engine mutex to be released before the thread
        waits for more incoming network messages.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_recovery_complete_at"></a>
        <a class="indexterm" name="idm46444256697104"></a>

        <a class="indexterm" name="idm46444256696064"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_recovery_complete_at"><code class="literal">group_replication_recovery_complete_at</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_recovery_complete_at"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-recovery-complete-at=value</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_recovery_complete_at">group_replication_recovery_complete_at</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>Enumeration</td>
</tr><tr><td scope="row"><span class="bold"><strong>Default Value</strong></span></td>
<td><code class="literal">TRANSACTIONS_APPLIED</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Valid Values</strong></span></td>
<td><p class="valid-value"><code class="literal">TRANSACTIONS_CERTIFIED</code></p><p class="valid-value"><code class="literal">TRANSACTIONS_APPLIED</code></p></td>
</tr></tbody></table>
</div>
<p>
        The policy applied during the distributed recovery process when
        handling cached transactions after state transfer. This option
        specifies whether a member is marked online after it has
        received all transactions that it missed before it joined the
        group (<code class="literal">TRANSACTIONS_CERTIFIED</code>) or after it
        has received and applied them
        (<code class="literal">TRANSACTIONS_APPLIED</code>).
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_recovery_compression_algorithm"></a>
        <a class="link" href="group-replication.html#sysvar_group_replication_recovery_compression_algorithm"><code class="literal">group_replication_recovery_compression_algorithm</code></a>
</p><a class="indexterm" name="idm46444256656448"></a><a class="indexterm" name="idm46444256655328"></a>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_recovery_compression_algorithm"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-recovery-compression-algorithm=value</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Introduced</strong></span></td>
<td>8.0.18</td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_recovery_compression_algorithm">group_replication_recovery_compression_algorithm</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>Set</td>
</tr><tr><td scope="row"><span class="bold"><strong>Default Value</strong></span></td>
<td><code class="literal">uncompressed</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Valid Values</strong></span></td>
<td><p class="valid-value"><code class="literal">zlib</code></p><p class="valid-value"><code class="literal">zstd</code></p><p class="valid-value"><code class="literal">uncompressed</code></p></td>
</tr></tbody></table>
</div>
<p>
        The compression algorithms permitted for Group Replication
        distributed recovery connections for state transfer from a
        donor's binary log. The available algorithms are the same as for
        the
        <a class="link" href="server-administration.html#sysvar_protocol_compression_algorithms"><code class="literal">protocol_compression_algorithms</code></a>
        system variable. For more information, see
        <a class="xref" href="programs.html#connection-compression-control" title="4.2.6 Connection Compression Control">Section 4.2.6, “Connection Compression Control”</a>.
      </p><p>
        This setting does not apply if the server has been set up to
        support cloning (see
        <a class="xref" href="group-replication.html#group-replication-cloning" title="18.4.3.1 Cloning for Distributed Recovery">Section 18.4.3.1, “Cloning for Distributed Recovery”</a>) and a remote
        cloning operation is used during distributed recovery. For this
        method of state transfer, the clone plugin's
        <a class="link" href="server-administration.html#sysvar_clone_enable_compression"><code class="literal">clone_enable_compression</code></a>
        setting applies.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_recovery_get_public_key"></a>
        <a class="link" href="group-replication.html#sysvar_group_replication_recovery_get_public_key"><code class="literal">group_replication_recovery_get_public_key</code></a>
</p><a class="indexterm" name="idm46444256610320"></a><a class="indexterm" name="idm46444256609200"></a>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_recovery_get_public_key"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-recovery-get-public-key[={OFF|ON}]</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_recovery_get_public_key">group_replication_recovery_get_public_key</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>Boolean</td>
</tr><tr><td scope="row"><span class="bold"><strong>Default Value</strong></span></td>
<td><code class="literal">OFF</code></td>
</tr></tbody></table>
</div>
<p>
        Whether to request from the master the public key required for
        RSA key pair-based password exchange. If
        <a class="link" href="group-replication.html#sysvar_group_replication_recovery_public_key_path"><code class="literal">group_replication_recovery_public_key_path</code></a>
        is set to a valid public key file, it takes precedence over
        <a class="link" href="group-replication.html#sysvar_group_replication_recovery_get_public_key"><code class="literal">group_replication_recovery_get_public_key</code></a>.
        This variable applies if you are not using SSL for distributed
        recovery over the <code class="literal">group_replication_recovery</code>
        channel
        (<a class="link" href="group-replication.html#sysvar_group_replication_recovery_use_ssl"><code class="literal">group_replication_recovery_use_ssl=ON</code></a>),
        and the replication user account for Group Replication
        authenticates with the <code class="literal">caching_sha2_password</code>
        plugin (which is the default in MySQL 8.0). For more details,
        see
        <a class="xref" href="group-replication.html#group-replication-caching-sha2-user-credentials" title="Using Group Replication and the Caching SHA-2 User Credentials Plugin">Using Group Replication and the Caching SHA-2 User Credentials Plugin</a>.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_recovery_public_key_path"></a>
        <a class="link" href="group-replication.html#sysvar_group_replication_recovery_public_key_path"><code class="literal">group_replication_recovery_public_key_path</code></a>
</p><a class="indexterm" name="idm46444256570592"></a><a class="indexterm" name="idm46444256569472"></a>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_recovery_public_key_path"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-recovery-public-key-path=file_name</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_recovery_public_key_path">group_replication_recovery_public_key_path</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>File name</td>
</tr><tr><td scope="row"><span class="bold"><strong>Default Value</strong></span></td>
<td><code class="literal">NULL</code></td>
</tr></tbody></table>
</div>
<p>
        The path name to a file containing a slave-side copy of the
        public key required by the master for RSA key pair-based
        password exchange. The file must be in PEM format. If
        <a class="link" href="group-replication.html#sysvar_group_replication_recovery_public_key_path"><code class="literal">group_replication_recovery_public_key_path</code></a>
        is set to a valid public key file, it takes precedence over
        <a class="link" href="group-replication.html#sysvar_group_replication_recovery_get_public_key"><code class="literal">group_replication_recovery_get_public_key</code></a>.
        This variable applies if you are not using SSL for distributed
        recovery over the <code class="literal">group_replication_recovery</code>
        channel (so
        <a class="link" href="group-replication.html#sysvar_group_replication_recovery_use_ssl"><code class="literal">group_replication_recovery_use_ssl</code></a>
        is set to <code class="literal">OFF</code>), and the replication user
        account for Group Replication authenticates with the
        <code class="literal">caching_sha2_password</code> plugin (which is the
        default in MySQL 8.0) or the <code class="literal">sha256_password</code>
        plugin. (For <code class="literal">sha256_password</code>, setting
        <code class="literal">group_replication_recovery_public_key_path</code>
        applies only if MySQL was built using OpenSSL.) For more
        details, see
        <a class="xref" href="group-replication.html#group-replication-caching-sha2-user-credentials" title="Using Group Replication and the Caching SHA-2 User Credentials Plugin">Using Group Replication and the Caching SHA-2 User Credentials Plugin</a>.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_recovery_reconnect_interval"></a>
        <a class="indexterm" name="idm46444256529184"></a>

        <a class="indexterm" name="idm46444256528064"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_recovery_reconnect_interval"><code class="literal">group_replication_recovery_reconnect_interval</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_recovery_reconnect_interval"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-recovery-reconnect-interval=#</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_recovery_reconnect_interval">group_replication_recovery_reconnect_interval</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>Integer</td>
</tr><tr><td scope="row"><span class="bold"><strong>Default Value</strong></span></td>
<td><code class="literal">60</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Minimum Value</strong></span></td>
<td><code class="literal">0</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Maximum Value</strong></span></td>
<td><code class="literal">31536000</code></td>
</tr></tbody></table>
</div>
<p>
        The sleep time, in seconds, between reconnection attempts when
        no suitable donor was found in the group for distributed
        recovery.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_recovery_retry_count"></a>
        <a class="indexterm" name="idm46444256489760"></a>

        <a class="indexterm" name="idm46444256488720"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_recovery_retry_count"><code class="literal">group_replication_recovery_retry_count</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_recovery_retry_count"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-recovery-retry-count=#</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_recovery_retry_count">group_replication_recovery_retry_count</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>Integer</td>
</tr><tr><td scope="row"><span class="bold"><strong>Default Value</strong></span></td>
<td><code class="literal">10</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Minimum Value</strong></span></td>
<td><code class="literal">0</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Maximum Value</strong></span></td>
<td><code class="literal">31536000</code></td>
</tr></tbody></table>
</div>
<p>
        The number of times that the member that is joining tries to
        connect to the available donors for distributed recovery before
        giving up.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_recovery_ssl_ca"></a>
        <a class="indexterm" name="idm46444256450416"></a>

        <a class="indexterm" name="idm46444256449376"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_recovery_ssl_ca"><code class="literal">group_replication_recovery_ssl_ca</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_recovery_ssl_ca"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-recovery-ssl-ca=value</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_recovery_ssl_ca">group_replication_recovery_ssl_ca</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>String</td>
</tr></tbody></table>
</div>
<p>
        The path to a file that contains a list of trusted SSL
        certificate authorities for distributed recovery connections.
        See
        <a class="xref" href="group-replication.html#group-replication-secure-socket-layer-support-ssl" title="18.5.2 Group Replication Secure Socket Layer (SSL) Support">Section 18.5.2, “Group Replication Secure Socket Layer (SSL) Support”</a>
        for information on configuring SSL for recovery.
      </p><p>
        If this server has been set up to support cloning (see
        <a class="xref" href="group-replication.html#group-replication-cloning" title="18.4.3.1 Cloning for Distributed Recovery">Section 18.4.3.1, “Cloning for Distributed Recovery”</a>), and you have set
        <a class="link" href="group-replication.html#sysvar_group_replication_recovery_use_ssl"><code class="literal">group_replication_recovery_use_ssl</code></a>
        to <code class="literal">ON</code>, Group Replication automatically
        configures the setting for the clone SSL option
        <a class="link" href="server-administration.html#sysvar_clone_ssl_ca"><code class="literal">clone_ssl_ca</code></a> to match your
        setting for
        <a class="link" href="group-replication.html#sysvar_group_replication_recovery_ssl_ca"><code class="literal">group_replication_recovery_ssl_ca</code></a>.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_recovery_ssl_capath"></a>
        <a class="indexterm" name="idm46444256413632"></a>

        <a class="indexterm" name="idm46444256412592"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_recovery_ssl_capath"><code class="literal">group_replication_recovery_ssl_capath</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_recovery_ssl_capath"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-recovery-ssl-capath=value</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_recovery_ssl_capath">group_replication_recovery_ssl_capath</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>String</td>
</tr></tbody></table>
</div>
<p>
        The path to a directory that contains trusted SSL certificate
        authority certificates for distributed recovery connections. See
        <a class="xref" href="group-replication.html#group-replication-secure-socket-layer-support-ssl" title="18.5.2 Group Replication Secure Socket Layer (SSL) Support">Section 18.5.2, “Group Replication Secure Socket Layer (SSL) Support”</a>
        for information on configuring SSL for distributed recovery.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_recovery_ssl_cert"></a>
        <a class="indexterm" name="idm46444256382624"></a>

        <a class="indexterm" name="idm46444256381584"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_recovery_ssl_cert"><code class="literal">group_replication_recovery_ssl_cert</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_recovery_ssl_cert"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-recovery-ssl-cert=value</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_recovery_ssl_cert">group_replication_recovery_ssl_cert</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>String</td>
</tr></tbody></table>
</div>
<p>
        The name of the SSL certificate file to use for establishing a
        secure connection for distributed recovery. See
        <a class="xref" href="group-replication.html#group-replication-secure-socket-layer-support-ssl" title="18.5.2 Group Replication Secure Socket Layer (SSL) Support">Section 18.5.2, “Group Replication Secure Socket Layer (SSL) Support”</a>
        for information on configuring SSL for distributed recovery.
      </p><p>
        If this server has been set up to support cloning (see
        <a class="xref" href="group-replication.html#group-replication-cloning" title="18.4.3.1 Cloning for Distributed Recovery">Section 18.4.3.1, “Cloning for Distributed Recovery”</a>), and you have set
        <a class="link" href="group-replication.html#sysvar_group_replication_recovery_use_ssl"><code class="literal">group_replication_recovery_use_ssl</code></a>
        to <code class="literal">ON</code>, Group Replication automatically
        configures the setting for the clone SSL option
        <a class="link" href="server-administration.html#sysvar_clone_ssl_cert"><code class="literal">clone_ssl_cert</code></a> to match your
        setting for
        <a class="link" href="group-replication.html#sysvar_group_replication_recovery_ssl_cert"><code class="literal">group_replication_recovery_ssl_cert</code></a>.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_recovery_ssl_cipher"></a>
        <a class="indexterm" name="idm46444256345840"></a>

        <a class="indexterm" name="idm46444256344800"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_recovery_ssl_cipher"><code class="literal">group_replication_recovery_ssl_cipher</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_recovery_ssl_cipher"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-recovery-ssl-cipher=value</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_recovery_ssl_cipher">group_replication_recovery_ssl_cipher</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>String</td>
</tr></tbody></table>
</div>
<p>
        The list of permissible ciphers for SSL encryption. See
        <a class="xref" href="group-replication.html#group-replication-secure-socket-layer-support-ssl" title="18.5.2 Group Replication Secure Socket Layer (SSL) Support">Section 18.5.2, “Group Replication Secure Socket Layer (SSL) Support”</a>
        for information on configuring SSL for distributed recovery.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_recovery_ssl_crl"></a>
        <a class="indexterm" name="idm46444256314976"></a>

        <a class="indexterm" name="idm46444256313936"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_recovery_ssl_crl"><code class="literal">group_replication_recovery_ssl_crl</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_recovery_ssl_crl"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-recovery-ssl-crl=value</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_recovery_ssl_crl">group_replication_recovery_ssl_crl</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>File name</td>
</tr></tbody></table>
</div>
<p>
        The path to a directory that contains files containing
        certificate revocation lists. See
        <a class="xref" href="group-replication.html#group-replication-secure-socket-layer-support-ssl" title="18.5.2 Group Replication Secure Socket Layer (SSL) Support">Section 18.5.2, “Group Replication Secure Socket Layer (SSL) Support”</a>
        for information on configuring SSL for distributed recovery.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_recovery_ssl_crlpath"></a>
        <a class="indexterm" name="idm46444256284016"></a>

        <a class="indexterm" name="idm46444256282976"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_recovery_ssl_crlpath"><code class="literal">group_replication_recovery_ssl_crlpath</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_recovery_ssl_crlpath"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-recovery-ssl-crlpath=value</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_recovery_ssl_crlpath">group_replication_recovery_ssl_crlpath</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>Directory name</td>
</tr></tbody></table>
</div>
<p>
        The path to a directory that contains files containing
        certificate revocation lists. See
        <a class="xref" href="group-replication.html#group-replication-secure-socket-layer-support-ssl" title="18.5.2 Group Replication Secure Socket Layer (SSL) Support">Section 18.5.2, “Group Replication Secure Socket Layer (SSL) Support”</a>
        for information on configuring SSL for distributed recovery.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_recovery_ssl_key"></a>
        <a class="indexterm" name="idm46444256253120"></a>

        <a class="indexterm" name="idm46444256252080"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_recovery_ssl_key"><code class="literal">group_replication_recovery_ssl_key</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_recovery_ssl_key"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-recovery-ssl-key=value</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_recovery_ssl_key">group_replication_recovery_ssl_key</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>String</td>
</tr></tbody></table>
</div>
<p>
        The name of the SSL key file to use for establishing a secure
        connection. See
        <a class="xref" href="group-replication.html#group-replication-secure-socket-layer-support-ssl" title="18.5.2 Group Replication Secure Socket Layer (SSL) Support">Section 18.5.2, “Group Replication Secure Socket Layer (SSL) Support”</a>
        for information on configuring SSL for distributed recovery.
      </p><p>
        If this server has been set up to support cloning (see
        <a class="xref" href="group-replication.html#group-replication-cloning" title="18.4.3.1 Cloning for Distributed Recovery">Section 18.4.3.1, “Cloning for Distributed Recovery”</a>), and you have set
        <a class="link" href="group-replication.html#sysvar_group_replication_recovery_use_ssl"><code class="literal">group_replication_recovery_use_ssl</code></a>
        to <code class="literal">ON</code>, Group Replication automatically
        configures the setting for the clone SSL option
        <a class="link" href="server-administration.html#sysvar_clone_ssl_key"><code class="literal">clone_ssl_key</code></a> to match your
        setting for
        <a class="link" href="group-replication.html#sysvar_group_replication_recovery_ssl_key"><code class="literal">group_replication_recovery_ssl_key</code></a>.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_recovery_ssl_verify_server_cert"></a>
        <a class="indexterm" name="idm46444256216336"></a>

        <a class="indexterm" name="idm46444256215296"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_recovery_ssl_verify_server_cert"><code class="literal">group_replication_recovery_ssl_verify_server_cert</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_recovery_ssl_verify_server_cert"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-recovery-ssl-verify-server-cert[={OFF|ON}]</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_recovery_ssl_verify_server_cert">group_replication_recovery_ssl_verify_server_cert</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>Boolean</td>
</tr><tr><td scope="row"><span class="bold"><strong>Default Value</strong></span></td>
<td><code class="literal">OFF</code></td>
</tr></tbody></table>
</div>
<p>
        Make the distributed recovery connection check the server's
        Common Name value in the donor sent certificate. See
        <a class="xref" href="group-replication.html#group-replication-secure-socket-layer-support-ssl" title="18.5.2 Group Replication Secure Socket Layer (SSL) Support">Section 18.5.2, “Group Replication Secure Socket Layer (SSL) Support”</a>
        for information on configuring SSL for distributed recovery.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_recovery_tls_ciphersuites"></a>
        <a class="indexterm" name="idm46444256182128"></a>

        <a class="indexterm" name="idm46444256181088"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_recovery_tls_ciphersuites"><code class="literal">group_replication_recovery_tls_ciphersuites</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_recovery_tls_ciphersuites"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-recovery-tls-ciphersuites=value</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Introduced</strong></span></td>
<td>8.0.19</td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_recovery_tls_ciphersuites">group_replication_recovery_tls_ciphersuites</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>String</td>
</tr><tr><td scope="row"><span class="bold"><strong>Default Value</strong></span></td>
<td><code class="literal">NULL</code></td>
</tr></tbody></table>
</div>
<p>
        A colon-separated list of one or more permitted ciphersuites
        when TLSv1.3 is used for connection encryption for the
        distributed recovery connection, and this server instance is the
        client in the distributed recovery connection, that is, the
        joining member. If this system variable is set to
        <code class="literal">NULL</code> when TLSv1.3 is used (which is the
        default if you do not set the system variable), the ciphersuites
        that are enabled by default are allowed, as listed in
        <a class="xref" href="security.html#encrypted-connection-protocols-ciphers" title="6.3.2 Encrypted Connection TLS Protocols and Ciphers">Section 6.3.2, “Encrypted Connection TLS Protocols and Ciphers”</a>. If
        this system variable is set to the empty string, no ciphersuites
        are allowed, and TLSv1.3 will therefore not be used. This system
        variable is available from MySQL 8.0.19. See
        <a class="xref" href="group-replication.html#group-replication-secure-socket-layer-support-ssl" title="18.5.2 Group Replication Secure Socket Layer (SSL) Support">Section 18.5.2, “Group Replication Secure Socket Layer (SSL) Support”</a>
        for information on configuring SSL for distributed recovery.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_recovery_tls_version"></a>
        <a class="indexterm" name="idm46444256143456"></a>

        <a class="indexterm" name="idm46444256142416"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_recovery_tls_version"><code class="literal">group_replication_recovery_tls_version</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_recovery_tls_version"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-recovery-tls-version=value</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Introduced</strong></span></td>
<td>8.0.19</td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_recovery_tls_version">group_replication_recovery_tls_version</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>String</td>
</tr><tr><td scope="row"><span class="bold"><strong>Default Value</strong></span></td>
<td><code class="literal">TLSv1,TLSv1.1,TLSv1.2,TLSv1.3</code></td>
</tr></tbody></table>
</div>
<p>
        A comma-separated list of one or more permitted TLS protocols
        for connection encryption when this server instance is the
        client in the distributed recovery connection, that is, the
        joining member. Ensure the specified versions are contiguous
        (for example,
        <span class="quote">“<span class="quote"><code class="literal">TLSv1,TLSv1.1,TLSv1.2</code></span>”</span>). If
        this system variable is not set, the default
        <span class="quote">“<span class="quote"><code class="literal">TLSv1,TLSv1.1,TLSv1.2,TLSv1.3</code></span>”</span>
        is used. The group members involved in each distributed recovery
        connection as the client (joining member) and server (donor)
        negotiate the highest protocol version that they are both set up
        to support. This system variable is available from MySQL 8.0.19.
        See
        <a class="xref" href="group-replication.html#group-replication-secure-socket-layer-support-ssl" title="18.5.2 Group Replication Secure Socket Layer (SSL) Support">Section 18.5.2, “Group Replication Secure Socket Layer (SSL) Support”</a>
        for information on configuring SSL for distributed recovery.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_recovery_use_ssl"></a>
        <a class="indexterm" name="idm46444256104528"></a>

        <a class="indexterm" name="idm46444256103488"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_recovery_use_ssl"><code class="literal">group_replication_recovery_use_ssl</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_recovery_use_ssl"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-recovery-use-ssl[={OFF|ON}]</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_recovery_use_ssl">group_replication_recovery_use_ssl</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>Boolean</td>
</tr><tr><td scope="row"><span class="bold"><strong>Default Value</strong></span></td>
<td><code class="literal">OFF</code></td>
</tr></tbody></table>
</div>
<p>
        Whether Group Replication distributed recovery connections
        between group members should use SSL or not. See
        <a class="xref" href="group-replication.html#group-replication-secure-socket-layer-support-ssl" title="18.5.2 Group Replication Secure Socket Layer (SSL) Support">Section 18.5.2, “Group Replication Secure Socket Layer (SSL) Support”</a>
        for information on configuring SSL for distributed recovery.
      </p><p>
        If this server has been set up to support cloning (see
        <a class="xref" href="group-replication.html#group-replication-cloning" title="18.4.3.1 Cloning for Distributed Recovery">Section 18.4.3.1, “Cloning for Distributed Recovery”</a>), and you set this
        option to <code class="literal">ON</code>, Group Replication uses SSL for
        remote cloning operations as well as for state transfer from a
        donor's binary log. If you set this option to
        <code class="literal">OFF</code>, Group Replication does not use SSL for
        remote cloning operations.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_recovery_zstd_compression_level"></a>
        <a class="link" href="group-replication.html#sysvar_group_replication_recovery_zstd_compression_level"><code class="literal">group_replication_recovery_zstd_compression_level</code></a>
</p><a class="indexterm" name="idm46444256066272"></a><a class="indexterm" name="idm46444256065232"></a>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_recovery_zstd_compression_level"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-recovery-zstd-compression-level=#</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Introduced</strong></span></td>
<td>8.0.18</td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_recovery_zstd_compression_level">group_replication_recovery_zstd_compression_level</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>Integer</td>
</tr><tr><td scope="row"><span class="bold"><strong>Default Value</strong></span></td>
<td><code class="literal">3</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Minimum Value</strong></span></td>
<td><code class="literal">1</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Maximum Value</strong></span></td>
<td><code class="literal">22</code></td>
</tr></tbody></table>
</div>
<p>
        The compression level to use for Group Replication distributed
        recovery connections that use the <code class="literal">zstd</code>
        compression algorithm. The permitted levels are from 1 to 22,
        with larger values indicating increasing levels of compression.
        The default <code class="literal">zstd</code> compression level is 3. For
        distributed recovery connections that do not use
        <code class="literal">zstd</code> compression, this variable has no
        effect.
      </p><p>
        For more information, see
        <a class="xref" href="programs.html#connection-compression-control" title="4.2.6 Connection Compression Control">Section 4.2.6, “Connection Compression Control”</a>.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_single_primary_mode"></a>
        <a class="indexterm" name="idm46444256022016"></a>

        <a class="indexterm" name="idm46444256020976"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_single_primary_mode"><code class="literal">group_replication_single_primary_mode</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_single_primary_mode"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-single-primary-mode[={OFF|ON}]</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_single_primary_mode">group_replication_single_primary_mode</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>Boolean</td>
</tr><tr><td scope="row"><span class="bold"><strong>Default Value</strong></span></td>
<td><code class="literal">ON</code></td>
</tr></tbody></table>
</div>
<p>
        Instructs the group to automatically pick a single server to be
        the one that handles read/write workload. This server is the
        PRIMARY and all others are SECONDARIES.
      </p><p>
        This system variable is a group-wide configuration setting. It
        must have the same value on all group members, cannot be changed
        while Group Replication is running, and requires a full reboot
        of the group (a bootstrap by a server with
        <a class="link" href="group-replication.html#sysvar_group_replication_bootstrap_group"><code class="literal">group_replication_bootstrap_group=ON</code></a>)
        in order for the value change to take effect. From MySQL 8.0.16,
        you can use the
        <a class="link" href="sql-statements.html#udf_group-replication-switch-to-single-primary-mode"><code class="literal">group_replication_switch_to_single_primary_mode()</code></a>
        and
        <a class="link" href="sql-statements.html#udf_group-replication-switch-to-multi-primary-mode"><code class="literal">group_replication_switch_to_multi_primary_mode()</code></a>
        UDFs to change the value of this system variable while the group
        is still running. For more information, see
        <a class="xref" href="group-replication.html#group-replication-changing-group-mode" title="18.4.1.2 Changing a Group's Mode">Section 18.4.1.2, “Changing a Group's Mode”</a>.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_ssl_mode"></a>
        <a class="indexterm" name="idm46444255983328"></a>

        <a class="indexterm" name="idm46444255982224"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_ssl_mode"><code class="literal">group_replication_ssl_mode</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_ssl_mode"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-ssl-mode=value</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_ssl_mode">group_replication_ssl_mode</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>Enumeration</td>
</tr><tr><td scope="row"><span class="bold"><strong>Default Value</strong></span></td>
<td><code class="literal">DISABLED</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Valid Values</strong></span></td>
<td><p class="valid-value"><code class="literal">DISABLED</code></p><p class="valid-value"><code class="literal">REQUIRED</code></p><p class="valid-value"><code class="literal">VERIFY_CA</code></p><p class="valid-value"><code class="literal">VERIFY_IDENTITY</code></p></td>
</tr></tbody></table>
</div>
<p>
        Sets the security state of group communication connections
        between Group Replication members. The possible values are as
        follows:
</p>
<div class="variablelist">
<dl class="variablelist"><dt><span class="term">
            DISABLED
          </span></dt><dd><p>
              Establish an unencrypted connection (the default).
            </p></dd><dt><span class="term">
            REQUIRED
          </span></dt><dd><p>
              Establish a secure connection if the server supports
              secure connections.
            </p></dd><dt><span class="term">
            VERIFY_CA
          </span></dt><dd><p>
              Like <code class="literal">REQUIRED</code>, but additionally verify
              the server TLS certificate against the configured
              Certificate Authority (CA) certificates.
            </p></dd><dt><span class="term">
            VERIFY_IDENTITY
          </span></dt><dd><p>
              Like <code class="literal">VERIFY_CA</code>, but additionally verify
              that the server certificate matches the host to which the
              connection is attempted.
</p></dd></dl>
</div>
<p>
        See
        <a class="xref" href="group-replication.html#group-replication-secure-socket-layer-support-ssl" title="18.5.2 Group Replication Secure Socket Layer (SSL) Support">Section 18.5.2, “Group Replication Secure Socket Layer (SSL) Support”</a>
        for information on configuring SSL for group communication.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_start_on_boot"></a>
        <a class="indexterm" name="idm46444255933840"></a>

        <a class="indexterm" name="idm46444255932736"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_start_on_boot"><code class="literal">group_replication_start_on_boot</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_start_on_boot"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-start-on-boot[={OFF|ON}]</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_start_on_boot">group_replication_start_on_boot</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>Boolean</td>
</tr><tr><td scope="row"><span class="bold"><strong>Default Value</strong></span></td>
<td><code class="literal">ON</code></td>
</tr></tbody></table>
</div>
<p>
        Whether the server should start Group Replication or not during
        server start.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_tls_source"></a>
        <a class="link" href="group-replication.html#sysvar_group_replication_tls_source"><code class="literal">group_replication_tls_source</code></a>
</p><a class="indexterm" name="idm46444255899472"></a><a class="indexterm" name="idm46444255898368"></a>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_tls_source"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-tls-source=value</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Introduced</strong></span></td>
<td>8.0.21</td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_tls_source">group_replication_tls_source</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>Enumeration</td>
</tr><tr><td scope="row"><span class="bold"><strong>Default Value</strong></span></td>
<td><code class="literal">mysql_main</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Valid Values</strong></span></td>
<td><p class="valid-value"><code class="literal">mysql_main</code></p><p class="valid-value"><code class="literal">mysql_admin</code></p></td>
</tr></tbody></table>
</div>
<p>
        The source of TLS material for Group Replication.
</p>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Note
</div>
<p>
          This variable can be changed while Group Replication is
          running, but Group Replication must be restarted before the
          change takes effect.
</p>
</div>
</li><li class="listitem"><p><a name="sysvar_group_replication_transaction_size_limit"></a>
        <a class="indexterm" name="idm46444255859568"></a>

        <a class="indexterm" name="idm46444255858448"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_transaction_size_limit"><code class="literal">group_replication_transaction_size_limit</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_transaction_size_limit"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-transaction-size-limit=#</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_transaction_size_limit">group_replication_transaction_size_limit</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>Integer</td>
</tr><tr><td scope="row"><span class="bold"><strong>Default Value</strong></span></td>
<td><code class="literal">150000000</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Minimum Value</strong></span></td>
<td><code class="literal">0</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Maximum Value</strong></span></td>
<td><code class="literal">2147483647</code></td>
</tr></tbody></table>
</div>
<p>
        Configures the maximum transaction size in bytes which the
        replication group accepts. Transactions larger than this size
        are rolled back by the receiving member and are not broadcast to
        the group. Large transactions can cause problems for a
        replication group in terms of memory allocation, which can cause
        the system to slow down, or in terms of network bandwidth
        consumption, which can cause a member to be suspected of having
        failed because it is busy processing the large transaction.
      </p><p>
        When this system variable is set to 0 there is no limit to the
        size of transactions the group accepts. From MySQL 8.0, the
        default setting for this system variable is 150000000 bytes
        (approximately 143 MB). Adjust the value of this system variable
        depending on the maximum message size that you need the group to
        tolerate, bearing in mind that the time taken to process a
        transaction is proportional to its size. The value of
        <a class="link" href="group-replication.html#sysvar_group_replication_transaction_size_limit"><code class="literal">group_replication_transaction_size_limit</code></a>
        should be the same on all group members. For further mitigation
        strategies for large transactions, see
        <a class="xref" href="group-replication.html#group-replication-limitations" title="18.9.2 Group Replication Limitations">Section 18.9.2, “Group Replication Limitations”</a>.
      </p></li><li class="listitem"><p><a name="sysvar_group_replication_unreachable_majority_timeout"></a>
        <a class="indexterm" name="idm46444255816640"></a>

        <a class="indexterm" name="idm46444255815600"></a>

        <a class="link" href="group-replication.html#sysvar_group_replication_unreachable_majority_timeout"><code class="literal">group_replication_unreachable_majority_timeout</code></a>
</p>
<div class="informaltable">
<table frame="box" rules="all" summary="Properties for group_replication_unreachable_majority_timeout"><col width="30%"><col width="70%"><thead><tr><th scope="col">Property</th>
<th scope="col">Value</th>
</tr></thead><tbody><tr><td scope="row"><span class="bold"><strong>Command-Line Format</strong></span></td>
<td><code class="literal">--group-replication-unreachable-majority-timeout=#</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>System Variable</strong></span></td>
<td><code class="literal"><a class="link" href="group-replication.html#sysvar_group_replication_unreachable_majority_timeout">group_replication_unreachable_majority_timeout</a></code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Scope</strong></span></td>
<td>Global</td>
</tr><tr><td scope="row"><span class="bold"><strong>Dynamic</strong></span></td>
<td>Yes</td>
</tr><tr><td scope="row"><span class="bold"><strong><a class="link" href="optimization.html#optimizer-hints-set-var" title="Variable-Setting Hint Syntax"><code class="literal">SET_VAR</code></a> Hint Applies</strong></span></td>
<td>No</td>
</tr><tr><td scope="row"><span class="bold"><strong>Type</strong></span></td>
<td>Integer</td>
</tr><tr><td scope="row"><span class="bold"><strong>Default Value</strong></span></td>
<td><code class="literal">0</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Minimum Value</strong></span></td>
<td><code class="literal">0</code></td>
</tr><tr><td scope="row"><span class="bold"><strong>Maximum Value</strong></span></td>
<td><code class="literal">31536000</code></td>
</tr></tbody></table>
</div>
<p>
        Specifies a number of seconds for which members that suffer a
        network partition and cannot connect to the majority wait before
        leaving the group. In a group of 5 servers (S1,S2,S3,S4,S5), if
        there is a disconnection between (S1,S2) and (S3,S4,S5) there is
        a network partition. The first group (S1,S2) is now in a
        minority because it cannot contact more than half of the group.
        While the majority group (S3,S4,S5) remains running, the
        minority group waits for the specified time for a network
        reconnection. For a detailed description of this scenario, see
        <a class="xref" href="group-replication.html#group-replication-network-partitioning" title="18.4.4 Network Partitioning">Section 18.4.4, “Network Partitioning”</a>.
      </p><p>
        By default,
        <a class="link" href="group-replication.html#sysvar_group_replication_unreachable_majority_timeout"><code class="literal">group_replication_unreachable_majority_timeout</code></a>
        is set to 0, which means that members that find themselves in a
        minority due to a network partition wait forever to leave the
        group. If you set a timeout, when the specified time elapses,
        all pending transactions processed by the minority are rolled
        back, and the servers in the minority partition move to the
        <code class="literal">ERROR</code> state. If a member has the
        <a class="link" href="group-replication.html#sysvar_group_replication_autorejoin_tries"><code class="literal">group_replication_autorejoin_tries</code></a>
        system variable set to specify a number of auto-rejoin attempts,
        it proceeds to make the specified number of attempts to rejoin
        the group while in super read only mode. If the member does not
        have any auto-rejoin attempts specified, or if it has exhausted
        the specified number of attempts, it follows the action
        specified by the system variable
        <a class="link" href="group-replication.html#sysvar_group_replication_exit_state_action"><code class="literal">group_replication_exit_state_action</code></a>.
</p>
<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Warning
</div>
<p>
          When you have a symmetric group, with just two members for
          example (S0,S2), if there is a network partition and there is
          no majority, after the configured timeout all members enter
          the <code class="literal">ERROR</code> state.
</p>
</div>
<p>
        For more information on using this option, see
        <a class="xref" href="group-replication.html#group-replication-responses-failure-partition" title="18.6.6.2 Unreachable Majority Timeout">Section 18.6.6.2, “Unreachable Majority Timeout”</a>.
</p></li></ul>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="group-replication-status-variables"></a>Group Replication Status Variable</h3>

</div>

</div>

</div>
<p>
      This section describes the status variables which provide
      information about Group Replication. The variable has the
      following meaning:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
          <a class="link" href="server-administration.html#statvar_group_replication_primary_member"><code class="literal">group_replication_primary_member</code></a>
        </p><p>
          Shows the primary member's UUID when the group is operating in
          single-primary mode. If the group is operating in
          multi-primary mode, shows an empty string.
</p>
<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Warning
</div>
<p>
            The <code class="literal">group_replication_primary_member</code>
            status variable has been deprecated and is scheduled to be
            removed in a future version.
</p>
</div>
<p>
          See <a class="xref" href="group-replication.html#group-replication-find-primary" title="18.1.3.1.2 Finding the Primary">Section 18.1.3.1.2, “Finding the Primary”</a>.
</p></li></ul>
</div>

</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a name="group-replication-requirements-and-limitations"></a>18.9 Requirements and Limitations</h2>

</div>

</div>

</div>
<div class="toc">
<dl class="toc"><dt><span class="section"><a href="group-replication.html#group-replication-requirements">18.9.1 Group Replication Requirements</a></span></dt><dt><span class="section"><a href="group-replication.html#group-replication-limitations">18.9.2 Group Replication Limitations</a></span></dt></dl>
</div>
<a class="indexterm" name="idm46444255759088"></a><p>
    This section lists and explains the requirements and limitations of
    Group Replication.
</p>
<div class="section">

<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="group-replication-requirements"></a>18.9.1 Group Replication Requirements</h3>
</div>
</div>
</div>
<a class="indexterm" name="idm46444255756064"></a><p>
      Server instances that you want to use for Group Replication must
      satisfy the following requirements.
</p>
<div class="simplesect">

<div class="titlepage">
<div>

<div class="simple">
<h4 class="title"><a name="group-replication-infrastructure"></a>Infrastructure</h4>
</div>
</div>
</div>

<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p><b>InnoDB Storage Engine. </b>
              Data must be stored in the
              <a class="link" href="innodb-storage-engine.html" title="Chapter 15 The InnoDB Storage Engine"><code class="literal">InnoDB</code></a> transactional storage
              engine. Transactions are executed optimistically and then,
              at commit time, are checked for conflicts. If there are
              conflicts, in order to maintain consistency across the
              group, some transactions are rolled back. This means that
              a transactional storage engine is required. Moreover,
              <a class="link" href="innodb-storage-engine.html" title="Chapter 15 The InnoDB Storage Engine"><code class="literal">InnoDB</code></a> provides some
              additional functionality that enables better management
              and handling of conflicts when operating together with
              Group Replication. The use of other storage engines,
              including the temporary
              <a class="link" href="storage-engines.html#memory-storage-engine" title="16.3 The MEMORY Storage Engine"><code class="literal">MEMORY</code></a> storage engine, might
              cause errors in Group Replication. You can prevent the use
              of other storage engines by setting the
              <a class="link" href="server-administration.html#sysvar_disabled_storage_engines"><code class="literal">disabled_storage_engines</code></a>
              system variable on group members, for example:
            </p><pre data-lang="ini" class="programlisting">disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"</pre></li><li class="listitem"><p><b>Primary Keys. </b>
              Every table that is to be replicated by the group must
              have a defined primary key, or primary key equivalent
              where the equivalent is a non-null unique key. Such keys
              are required as a unique identifier for every row within a
              table, enabling the system to determine which transactions
              conflict by identifying exactly which rows each
              transaction has modified. Group Replication has its own
              built-in set of checks for primary keys or primary key
              equivalents, and does not use the checks carried out by
              the
              <a class="link" href="server-administration.html#sysvar_sql_require_primary_key"><code class="literal">sql_require_primary_key</code></a>
              system variable. You may set
              <code class="literal">sql_require_primary_key=ON</code> for a server
              instance where Group Replication is running, and you may
              set the <code class="literal">REQUIRE_TABLE_PRIMARY_KEY_CHECK</code>
              option of the <a class="link" href="sql-statements.html#change-master-to" title="13.4.2.1 CHANGE MASTER TO Statement"><code class="literal">CHANGE MASTER
              TO</code></a> statement to <code class="literal">ON</code> for a
              Group Replication channel. However, be aware that you
              might find some transactions that are permitted under
              Group Replication's built-in checks are not permitted
              under the checks carried out when you set
              <code class="literal">sql_require_primary_key=ON</code> or
              <code class="literal">REQUIRE_TABLE_PRIMARY_KEY_CHECK=ON</code>.
            </p></li><li class="listitem"><p><b>Network Performance. </b>
              MySQL Group Replication is designed to be deployed in a
              cluster environment where server instances are very close
              to each other. The performance and stabiity of a group can
              be impacted by both network latency and network bandwidth.
              Bi-directional communication must be maintained at all
              times between all group members. If either inbound or
              outbound communication is blocked for a server instance
              (for example, by a firewall, or by connectivity issues),
              the member cannot function in the group, and the group
              members (including the member with issues) might not be
              able to report the correct member status for the affected
              server instance.
            </p><p>
            From MySQL 8.0.14, you can use an IPv4 or IPv6 network
            infrastructure, or a mix of the two, for TCP communication
            between remote Group Replication servers. There is also
            nothing preventing Group Replication from operating over a
            virtual private network (VPN).
          </p><p>
            Also from MySQL 8.0.14, where Group Replication server
            instances are co-located and share a local group
            communication engine (XCom) instance, a dedicated input
            channel with lower overhead is used for communication where
            possible instead of the TCP socket. For certain Group
            Replication tasks that require communication between remote
            XCom instances, such as joining a group, the TCP network is
            still used, so network performance influences the group's
            performance.
</p></li></ul>
</div>

</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h4 class="title"><a name="group-replication-configuration"></a>Server Instance Configuration</h4>

</div>

</div>

</div>
<p>
        The following options must be configured as shown on server
        instances that are members of a group.
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p><b>Binary Log Active. </b>
              Set
              <a class="link" href="replication.html#sysvar_log_bin"><code class="literal">--log-bin[=log_file_name]</code></a>.
              MySQL Group Replication replicates binary log contents,
              therefore the binary log needs to be on for it to operate.
              This option is enabled by default. See
              <a class="xref" href="server-administration.html#binary-log" title="5.4.4 The Binary Log">Section 5.4.4, “The Binary Log”</a>.
            </p></li><li class="listitem"><p><b>Slave Updates Logged. </b>
              Set <a class="link" href="replication.html#sysvar_log_slave_updates"><code class="literal">--log-slave-updates</code></a>.
              This option is enabled by default. Group members need to
              log transactions that are received from their donors at
              joining time and applied through the replication applier,
              and to log all transactions that they receive and apply
              from the group. This enables Group Replication to carry
              out distributed recovery by state transfer from an
              existing group member's binary log.
            </p></li><li class="listitem"><p><b>Binary Log Row Format. </b>
              Set <a class="link" href="replication.html#sysvar_binlog_format"><code class="literal">--binlog-format=row</code></a>.
              Group Replication relies on row-based replication format
              to propagate changes consistently among the servers in the
              group. It relies on row-based infrastructure to be able to
              extract the necessary information to detect conflicts
              among transactions that execute concurrently in different
              servers in the group. From MySQL 8.0.19, the
              <code class="literal">REQUIRE_ROW_FORMAT</code> setting is
              automatically added to Group Replication's channels to
              enforce the use of row-based replication when the
              transactions are applied. See
              <a class="xref" href="replication.html#replication-formats" title="17.2.1 Replication Formats">Section 17.2.1, “Replication Formats”</a> and
              <a class="xref" href="replication.html#replication-privilege-checks" title="17.3.3 Replication Privilege Checks">Section 17.3.3, “Replication Privilege Checks”</a>.
            </p></li><li class="listitem"><p><b>Binary Log Checksums Off. </b>
              Set
              <a class="link" href="replication.html#sysvar_binlog_checksum"><code class="literal">--binlog-checksum=NONE</code></a>.
              Due to a design limitation of replication event checksums,
              Group Replication cannot make use of them, and they must
              be disabled.
            </p></li><li class="listitem"><p><b>Global Transaction Identifiers On. </b>
              Set <a class="link" href="replication.html#sysvar_gtid_mode"><code class="literal">gtid_mode=ON</code></a>. Group
              Replication uses global transaction identifiers to track
              exactly which transactions have been committed on every
              server instance and thus be able to infer which servers
              have executed transactions that could conflict with
              already committed transactions elsewhere. In other words,
              explicit transaction identifiers are a fundamental part of
              the framework to be able to determine which transactions
              may conflict. See <a class="xref" href="replication.html#replication-gtids" title="17.1.3 Replication with Global Transaction Identifiers">Section 17.1.3, “Replication with Global Transaction Identifiers”</a>.
            </p></li><li class="listitem"><p><b>Replication Information Repositories. </b>
              Set
              <a class="link" href="replication.html#sysvar_master_info_repository"><code class="literal">master_info_repository=TABLE</code></a>
              and
              <a class="link" href="replication.html#sysvar_relay_log_info_repository"><code class="literal">relay_log_info_repository=TABLE</code></a>.
              The replication applier needs to have the master
              information and relay log metadata written to the
              <code class="literal">mysql.slave_master_info</code> and
              <code class="literal">mysql.slave_relay_log_info</code> system
              tables. This ensures the Group Replication plugin has
              consistent recoverability and transactional management of
              the replication metadata. From MySQL 8.0.2, these options
              are set to <code class="literal">TABLE</code> by default, and from
              MySQL 8.0.3, the <code class="literal">FILE</code> setting is
              deprecated. See <a class="xref" href="replication.html#slave-logs-status" title="17.2.4.2 Slave Status Logs">Section 17.2.4.2, “Slave Status Logs”</a>.
            </p></li><li class="listitem"><p><b>Transaction Write Set Extraction. </b>
              Set
              <a class="link" href="replication.html#sysvar_transaction_write_set_extraction"><code class="literal">--transaction-write-set-extraction=XXHASH64</code></a>
              so that while collecting rows to log them to the binary
              log, the server collects the write set as well. The write
              set is based on the primary keys of each row and is a
              simplified and compact view of a tag that uniquely
              identifies the row that was changed. This tag is then used
              for detecting conflicts. This option is enabled by
              default.
            </p></li><li class="listitem"><p><b>Binary Log Dependency Tracking. </b>
              Setting
              <a class="link" href="replication.html#sysvar_binlog_transaction_dependency_tracking"><code class="literal">binlog_transaction_dependency_tracking=WRITESET_SESSION</code></a>
              can improve performance for a group member, depending on
              the group's workload. Group Replication carries out its
              own parallelization after certification when applying
              transactions from the relay log, independently of the
              value set for
              <a class="link" href="replication.html#sysvar_binlog_transaction_dependency_tracking"><code class="literal">binlog_transaction_dependency_tracking</code></a>.
              However, the value of
              <a class="link" href="replication.html#sysvar_binlog_transaction_dependency_tracking"><code class="literal">binlog_transaction_dependency_tracking</code></a>
              does affect how transactions are written to the binary
              logs on Group Replication members. The dependency
              information in those logs is used to assist the process of
              state transfer from a donor's binary log for distributed
              recovery, which takes place whenever a member joins or
              rejoins the group.
            </p></li><li class="listitem"><p><b>Default Table Encryption. </b>
              Set
              <a class="link" href="server-administration.html#sysvar_default_table_encryption"><code class="literal">--default-table-encryption</code></a>
              to the same value on all group members. Default schema and
              tablespace encryption can be either enabled
              (<code class="literal">ON</code>) or disabled
              (<code class="literal">OFF</code>, the default) as long as the
              setting is the same on all members.
            </p></li><li class="listitem"><p><b>Lower Case Table Names. </b>
              Set
              <a class="link" href="server-administration.html#sysvar_lower_case_table_names"><code class="literal">--lower-case-table-names</code></a>
              to the same value on all group members. A setting of 1 is
              correct for the use of the
              <a class="link" href="innodb-storage-engine.html" title="Chapter 15 The InnoDB Storage Engine"><code class="literal">InnoDB</code></a> storage engine, which
              is required for Group Replication. Note that this setting
              is not the default on all platforms.
            </p></li><li class="listitem"><p><b>Multithreaded Appliers. </b>

              Group Replication members can be configured as
              multithreaded slaves, enabling transactions to be applied
              in parallel. A nonzero value for
              <a class="link" href="replication.html#sysvar_slave_parallel_workers"><code class="literal">slave_parallel_workers</code></a>
              enables the multithreaded applier on the member, and up to
              1024 parallel applier threads can be specified. Setting
              <a class="link" href="replication.html#sysvar_slave_preserve_commit_order"><code class="literal">slave_preserve_commit_order=1</code></a>
              ensures that the final commit of parallel transactions is
              in the same order as the original transactions, as
              required for Group Replication, which relies on
              consistency mechanisms built around the guarantee that all
              participating members receive and apply committed
              transactions in the same order. Finally, the setting
              <a class="link" href="replication.html#sysvar_slave_parallel_type"><code class="literal">slave_parallel_type=LOGICAL_CLOCK</code></a>,
              which specifies the policy used to decide which
              transactions are allowed to execute in parallel on the
              slave, is required with
              <a class="link" href="replication.html#sysvar_slave_preserve_commit_order"><code class="literal">slave_preserve_commit_order=1</code></a>.


              Setting
              <a class="link" href="replication.html#sysvar_slave_parallel_workers"><code class="literal">slave_parallel_workers=0</code></a>
              disables parallel execution and gives the slave a single
              applier thread and no coordinator thread. With that
              setting, the
              <a class="link" href="replication.html#sysvar_slave_parallel_type"><code class="literal">slave_parallel_type</code></a> and
              <a class="link" href="replication.html#sysvar_slave_preserve_commit_order"><code class="literal">slave_preserve_commit_order</code></a>
              options have no effect and are ignored.
</p></li></ul>
</div>

</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="group-replication-limitations"></a>18.9.2 Group Replication Limitations</h3>

</div>

</div>

</div>
<a class="indexterm" name="idm46444255668336"></a><p>
      The following known limitations exist for Group Replication. Note
      that the limitations and issues described for multi-primary mode
      groups can also apply in single-primary mode clusters during a
      failover event, while the newly elected primary flushes out its
      applier queue from the old primary.
</p>
<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Tip
</div>
<p>
        Group Replication is built on GTID based replication, therefore
        you should also be aware of
        <a class="xref" href="replication.html#replication-gtids-restrictions" title="17.1.3.6 Restrictions on Replication with GTIDs">Section 17.1.3.6, “Restrictions on Replication with GTIDs”</a>.
</p>
</div>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p><b><code class="literal">--upgrade=MINIMAL</code> option. </b>
            Group Replication cannot be started following a MySQL Server
            upgrade that uses the MINIMAL option
            (<code class="literal">--upgrade=MINIMAL</code>), which does not
            upgrade system tables on which the replication internals
            depend.
          </p></li><li class="listitem"><p><b>Gap Locks. </b>
            The certification process does not take into account
            <a class="link" href="glossary.html#glos_gap_lock" title="gap lock">gap locks</a>, as
            information about gap locks is not available outside of
            <a class="link" href="innodb-storage-engine.html" title="Chapter 15 The InnoDB Storage Engine"><code class="literal">InnoDB</code></a>. See
            <a class="xref" href="innodb-storage-engine.html#innodb-gap-locks" title="Gap Locks">Gap Locks</a> for more information.
</p>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Note
</div>
<p>
            Unless you rely on <a class="link" href="innodb-storage-engine.html#isolevel_repeatable-read"><code class="literal">REPEATABLE
            READ</code></a> semantics in your applications, we recommend
            using the <a class="link" href="innodb-storage-engine.html#isolevel_read-committed"><code class="literal">READ COMMITTED</code></a>
            isolation level with Group Replication. InnoDB does not use
            gap locks in <a class="link" href="innodb-storage-engine.html#isolevel_read-committed"><code class="literal">READ
            COMMITTED</code></a>, which aligns the local conflict
            detection within InnoDB with the distributed conflict
            detection performed by Group Replication.
</p>
</div>
</li><li class="listitem"><p><b>Table Locks and Named Locks. </b>
            The certification process does not take into account table
            locks (see <a class="xref" href="sql-statements.html#lock-tables" title="13.3.6 LOCK TABLES and UNLOCK TABLES Statements">Section 13.3.6, “LOCK TABLES and UNLOCK TABLES Statements”</a>) or named locks
            (see <a class="link" href="functions.html#function_get-lock"><code class="literal">GET_LOCK()</code></a>).
          </p></li><li class="listitem"><p><b>Replication Event Checksums. </b>
            Due to a design limitation of replication event checksums,
            Group Replication cannot currently make use of them.
            Therefore set
            <a class="link" href="replication.html#sysvar_binlog_checksum"><code class="literal">--binlog-checksum=NONE</code></a>.
          </p></li><li class="listitem"><p><b>SERIALIZABLE Isolation Level. </b>
            <a class="link" href="innodb-storage-engine.html#isolevel_serializable"><code class="literal">SERIALIZABLE</code></a> isolation
            level is not supported in multi-primary groups by default.
            Setting a transaction isolation level to
            <code class="literal">SERIALIZABLE</code> configures Group Replication
            to refuse to commit the transaction.
          </p></li><li class="listitem"><p><b>Concurrent DDL versus DML Operations. </b>
            Concurrent data definition statements and data manipulation
            statements executing against the same object but on
            different servers is not supported when using multi-primary
            mode. During execution of Data Definition Language (DDL)
            statements on an object, executing concurrent Data
            Manipulation Language (DML) on the same object but on a
            different server instance has the risk of conflicting DDL
            executing on different instances not being detected.
          </p></li><li class="listitem"><p><b>Foreign Keys with Cascading Constraints. </b>
            Multi-primary mode groups (members all configured with
            <a class="link" href="group-replication.html#sysvar_group_replication_single_primary_mode"><code class="literal">group_replication_single_primary_mode=OFF</code></a>)
            do not support tables with multi-level foreign key
            dependencies, specifically tables that have defined
            <code class="literal">CASCADING</code>
            <a class="link" href="glossary.html#glos_foreign_key_constraint" title="FOREIGN KEY constraint"> foreign key
            constraints</a>. This is because foreign key constraints
            that result in cascading operations executed by a
            multi-primary mode group can result in undetected conflicts
            and lead to inconsistent data across the members of the
            group. Therefore we recommend setting
            <a class="link" href="group-replication.html#sysvar_group_replication_enforce_update_everywhere_checks"><code class="literal">group_replication_enforce_update_everywhere_checks=ON</code></a>
            on server instances used in multi-primary mode groups to
            avoid undetected conflicts.
          </p><p>
          In single-primary mode this is not a problem as it does not
          allow concurrent writes to multiple members of the group and
          thus there is no risk of undetected conflicts.
        </p></li><li class="listitem"><p><b>Multi-primary Mode Deadlock. </b>
            When a group is operating in multi-primary mode,
            <code class="literal">SELECT .. FOR UPDATE</code> statements can
            result in a deadlock. This is because the lock is not shared
            across the members of the group, therefore the expectation
            for such a statement might not be reached.
          </p></li><li class="listitem"><p><b>Replication Filters. </b>
            Global replication filters cannot be used on a MySQL server
            instance that is configured for Group Replication, because
            filtering transactions on some servers would make the group
            unable to reach agreement on a consistent state. Channel
            specific replication filters can be used on replication
            channels that are not directly involved with Group
            Replication, such as where a group member also acts as a
            replication slave to a master that is outside the group.
            They cannot be used on the
            <code class="literal">group_replication_applier</code> or
            <code class="literal">group_replication_recovery</code> channels.
          </p></li><li class="listitem"><p><b>Encrypted Connections. </b>
            Support for the TLSv1.3 protocol is available in MySQL
            Server as of MySQL 8.0.16, provided that MySQL was compiled
            using OpenSSL 1.1.1 or higher. In MySQL 8.0.16 and MySQL
            8.0.17, if the server supports TLSv1.3, the protocol is not
            supported in the group communication engine and cannot be
            used by Group Replication. Group Replication supports
            TLSv1.3 from MySQL 8.0.18, where it can be used for group
            communication connections and distributed recovery
            connections.
          </p><p>
          In MySQL 8.0.18, TLSv1.3 can be used in Group Replication for
          the distributed recovery connection, but the
          <a class="link" href="group-replication.html#sysvar_group_replication_recovery_tls_version"><code class="literal">group_replication_recovery_tls_version</code></a>
          and
          <a class="link" href="group-replication.html#sysvar_group_replication_recovery_tls_ciphersuites"><code class="literal">group_replication_recovery_tls_ciphersuites</code></a>
          system variables are not available. The donor servers must
          therefore permit the use of at least one TLSv1.3 ciphersuite
          that is enabled by default, as listed in
          <a class="xref" href="security.html#encrypted-connection-protocols-ciphers" title="6.3.2 Encrypted Connection TLS Protocols and Ciphers">Section 6.3.2, “Encrypted Connection TLS Protocols and Ciphers”</a>. From
          MySQL 8.0.19, you can use the options to configure client
          support for any selection of ciphersuites, including only
          non-default ciphersuites if you want.
        </p></li><li class="listitem"><p><b>Cloning Operations. </b>
            Group Replication initiates and manages cloning operations
            for distributed recovery, but group members that have been
            set up to support cloning may also participate in cloning
            operations that a user initiates manually. In releases
            before MySQL 8.0.20, you cannot initiate a cloning operation
            manually if the operation involves a group member on which
            Group Replication is running. From MySQL 8.0.20, you can do
            this, provided that the cloning operation does not remove
            and replace the data on the recipient. The statement to
            initiate the cloning operation must therefore include the
            <code class="literal">DATA DIRECTORY</code> clause if Group
            Replication is running. See
            <a class="xref" href="group-replication.html#group-replication-cloning-manual" title="18.4.3.1.4 Cloning for Other Purposes">Section 18.4.3.1.4, “Cloning for Other Purposes”</a>.
</p></li></ul>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h4 class="title"><a name="idm46444255615424"></a>Limit on Group Size</h4>

</div>

</div>

</div>
<p>
        The maximum number of MySQL servers that can be members of a
        single replication group is 9. If further members attempt to
        join the group, their request is refused. This limit has been
        identified from testing and benchmarking as a safe boundary
        where the group performs reliably on a stable local area
        network.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h4 class="title"><a name="group-replication-limitations-transaction-size"></a>Limits on Transaction Size</h4>

</div>

</div>

</div>
<p>
        If an individual transaction results in message contents which
        are large enough that the message cannot be copied between group
        members over the network within a 5-second window, members can
        be suspected of having failed, and then expelled, just because
        they are busy processing the transaction. Large transactions can
        also cause the system to slow due to problems with memory
        allocation. To avoid these issues use the following mitigations:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            If unnecessary expulsions occur due to large messages, use
            the system variable
            <a class="link" href="group-replication.html#sysvar_group_replication_member_expel_timeout"><code class="literal">group_replication_member_expel_timeout</code></a>
            to allow additional time before a member under suspicion of
            having failed is expelled. You can allow up to an hour after
            the initial 5-second detection period before a suspect
            member is expelled from the group.
          </p></li><li class="listitem"><p>
            Where possible, try and limit the size of your transactions
            before they are handled by Group Replication. For example,
            split up files used with <code class="literal">LOAD DATA</code> into
            smaller chunks.
          </p></li><li class="listitem"><p>
            Use the system variable
            <a class="link" href="group-replication.html#sysvar_group_replication_transaction_size_limit"><code class="literal">group_replication_transaction_size_limit</code></a>
            to specify a maximum transaction size that the group will
            accept. In MySQL 8.0, this system variable defaults to a
            maximum transaction size of 150000000 bytes (approximately
            143 MB). Transactions above this size are rolled back and
            are not sent to Group Replication's Group Communication
            System (GCS) for distribution to the group. Adjust the value
            of this variable depending on the maximum message size that
            you need the group to tolerate, bearing in mind that the
            time taken to process a transaction is proportional to its
            size.
          </p></li><li class="listitem"><p>
            Use the system variable
            <a class="link" href="group-replication.html#sysvar_group_replication_compression_threshold"><code class="literal">group_replication_compression_threshold</code></a>
            to specify a message size above which compression is
            applied. This system variable defaults to 1000000 bytes (1
            MB), so large messages are automatically compressed.
            Compression is carried out by Group Replication's Group
            Communication System (GCS) when it receives a message that
            was permitted by the
            <a class="link" href="group-replication.html#sysvar_group_replication_transaction_size_limit"><code class="literal">group_replication_transaction_size_limit</code></a>
            setting but exceeds the
            <a class="link" href="group-replication.html#sysvar_group_replication_compression_threshold"><code class="literal">group_replication_compression_threshold</code></a>
            setting. For more information, see
            <a class="xref" href="group-replication.html#group-replication-message-compression" title="18.6.3 Message Compression">Section 18.6.3, “Message Compression”</a>.
          </p></li><li class="listitem"><p>
            Use the system variable
            <a class="link" href="group-replication.html#sysvar_group_replication_communication_max_message_size"><code class="literal">group_replication_communication_max_message_size</code></a>
            to specify a message size above which messages are
            fragmented. This system variable defaults to 10485760 bytes
            (10 MiB), so large messages are automatically fragmented.
            GCS carries out fragmentation after compression if the
            compressed message still exceeds the
            <a class="link" href="group-replication.html#sysvar_group_replication_communication_max_message_size"><code class="literal">group_replication_communication_max_message_size</code></a>
            limit. In order for a replication group to use
            fragmentation, all group members must be at MySQL 8.0.16 or
            above, and the Group Replication communication protocol
            version in use by the group must allow fragmentation. For
            more information, see
            <a class="xref" href="group-replication.html#group-replication-performance-message-fragmentation" title="18.6.4 Message Fragmentation">Section 18.6.4, “Message Fragmentation”</a>.
</p></li></ul>
</div>
<p>
        The maximum transaction size, message compression, and message
        fragmentation can all be deactivated by specifying a zero value
        for the relevant system variable. If you have deactivated all
        these safeguards, the upper size limit for a message that can be
        handled by the applier thread on a member of a replication group
        is the value of the member's
        <a class="link" href="replication.html#sysvar_slave_max_allowed_packet"><code class="literal">slave_max_allowed_packet</code></a> system
        variable, which has a default and maximum value of 1073741824
        bytes (1 GB). A message that exceeds this limit fails when the
        receiving member attempts to handle it. The upper size limit for
        a message that a group member can originate and attempt to
        transmit to the group is 4294967295 bytes (approximately 4 GB).
        This is a hard limit on the packet size that is accepted by the
        group communication engine for Group Replication (XCom, a Paxos
        variant), which receives messages after GCS has handled them. A
        message that exceeds this limit fails when the originating
        member attempts to broadcast it.
</p>
</div>

</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a name="group-replication-frequently-asked-questions"></a>18.10 Frequently Asked Questions</h2>

</div>

</div>

</div>
<a class="indexterm" name="idm46444255588432"></a><p>
    This section provides answers to frequently asked questions.
</p>
<div class="simplesect">

<div class="titlepage">
<div>

<div class="simple">
<h3 class="title"><a name="group-replication-maximum-number-servers"></a>What is the maximum number of MySQL servers in a group?</h3>
</div>
</div>
</div>
<p>
      A group can consist of maximum 9 servers. Attempting to add
      another server to a group with 9 members causes the request to
      join to be refused. This limit has been identified from testing
      and benchmarking as a safe boundary where the group performs
      reliably on a stable local area network.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="group-replication-servers-in-a-group-connected"></a>How are servers in a group connected?</h3>

</div>

</div>

</div>
<p>
      Servers in a group connect to the other servers in the group by
      opening a peer-to-peer TCP connection. These connections are only
      used for internal communication and message passing between
      servers in the group. This address is configured by the
      <a class="link" href="group-replication.html#sysvar_group_replication_local_address"><code class="literal">group_replication_local_address</code></a>
      variable.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="group-replication-what-is-the-group-replication-bootstrap-group-option-used-for"></a>What is the group_replication_bootstrap_group option used for?</h3>

</div>

</div>

</div>
<p>
      The bootstrap flag instructs a member to
      <span class="emphasis"><em>create</em></span> a group and act as the initial seed
      server. The second member joining the group needs to ask the
      member that bootstrapped the group to dynamically change the
      configuration in order for it to be added to the group.
    </p><p>
      A member needs to bootstrap the group in two scenarios. When the
      group is originally created, or when shutting down and restarting
      the entire group.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="group-replication-credentials-for-recovery"></a>How do I set credentials for the distributed recovery process?</h3>

</div>

</div>

</div>
<p>
      You pre-configure the Group Replication recovery channel
      credentials using the <a class="link" href="sql-statements.html#change-master-to" title="13.4.2.1 CHANGE MASTER TO Statement"><code class="literal">CHANGE MASTER
      TO</code></a> statement.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="group-replication-scale-out-write-load"></a>Can I scale-out my write-load using Group Replication?</h3>

</div>

</div>

</div>
<p>
      Not directly, but MySQL Group replication is a shared nothing full
      replication solution, where all servers in the group replicate the
      same amount of data. Therefore if one member in the group writes N
      bytes to storage as the result of a transaction commit operation,
      then roughly N bytes are written to storage on other members as
      well, because the transaction is replicated everywhere.
    </p><p>
      However, given that other members do not have to do the same
      amount of processing that the original member had to do when it
      originally executed the transaction, they apply the changes
      faster. Transactions are replicated in a format that is used to
      apply row transformations only, without having to re-execute
      transactions again (row-based format).
    </p><p>
      Furthermore, given that changes are propagated and applied in
      row-based format, this means that they are received in an
      optimized and compact format, and likely reducing the number of IO
      operations required when compared to the originating member.
    </p><p>
      To summarize, you can scale-out processing, by spreading conflict
      free transactions throughout different members in the group. And
      you can likely scale-out a small fraction of your IO operations,
      since remote servers receive only the necessary changes to
      read-modify-write changes to stable storage.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="group-replication-performance-compared"></a>Does Group Replication require more network bandwidth and CPU, when
compared to simple replication and under the same workload?</h3>
</div>
</div>
</div>
<p>
      Some additional load is expected because servers need to be
      constantly interacting with each other for synchronization
      purposes. It is difficult to quantify how much more data. It also
      depends on the size of the group (three servers puts less stress
      on the bandwidth requirements than nine servers in the group).
    </p><p>
      Also the memory and CPU footprint are larger, because more complex
      work is done for the server synchronization part and for the group
      messaging.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="group-replication-deploy-across-wide-area-network"></a>Can I deploy Group Replication across wide-area networks?</h3>

</div>

</div>

</div>
<p>
      Yes, but the network connection between each member
      <span class="emphasis"><em>must</em></span> be reliable and have suitable
      perfomance. Low latency, high bandwidth network connections are a
      requirement for optimal performance.
    </p><p>
      If network bandwidth alone is an issue, then
      <a class="xref" href="group-replication.html#group-replication-message-compression" title="18.6.3 Message Compression">Section 18.6.3, “Message Compression”</a> can be
      used to lower the bandwidth required. However, if the network
      drops packets, leading to re-transmissions and higher end-to-end
      latency, throughput and latency are both negatively affected.
</p>
<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Warning
</div>
<p>
        When the network round-trip time (RTT) between any group members
        is 5 seconds or more you could encounter problems as the
        built-in failure detection mechanism could be incorrectly
        triggered.
</p>
</div>

</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="group-replication-automatically-rejoin-temporary-problems"></a>Do members automatically rejoin a group in case of temporary
connectivity problems?</h3>
</div>
</div>
</div>
<p>
      This depends on the reason for the connectivity problem. If the
      connectivity problem is transient and the reconnection is quick
      enough that the failure detector is not aware of it, then the
      server may not be removed from the group. If it is a
      "long" connectivity problem, then the failure detector
      eventually suspects a problem and the server is removed from the
      group.
    </p><p>
      From MySQL 8.0, you can activate two settings to increase the
      chances of a member remaining in or rejoining a group:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
          <a class="link" href="group-replication.html#sysvar_group_replication_member_expel_timeout"><code class="literal">group_replication_member_expel_timeout</code></a>
          increases the time between the creation of a suspicion (which
          happens after an initial 5-second detection period) and the
          expulsion of the member. You can set a waiting period of up to
          1 hour.
        </p></li><li class="listitem"><p>
          <a class="link" href="group-replication.html#sysvar_group_replication_autorejoin_tries"><code class="literal">group_replication_autorejoin_tries</code></a>
          makes a member try to rejoin the group after an expulsion or
          unreachable majority timeout. The member makes the specified
          number of auto-rejoin attempts five minutes apart.
</p></li></ul>
</div>
<p>
      If a server is expelled from the group and any auto-rejoin
      attempts do not succeed, you need to join it back again. In other
      words, after a server is removed explicitly from the group you
      need to rejoin it manually (or have a script doing it
      automatically).
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="group-replication-member-excluded"></a>When is a member excluded from a group?</h3>

</div>

</div>

</div>
<p>
      If the member becomes silent, the other members remove it from the
      group configuration. In practice this may happen when the member
      has crashed or there is a network disconnection.
    </p><p>
      The failure is detected after a given timeout elapses for a given
      member and a new configuration without the silent member in it is
      created.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="group-replication-node-lag"></a>What happens when one node is significantly lagging behind?</h3>

</div>

</div>

</div>
<p>
      There is no method for defining policies for when to expel members
      automatically from the group. You need to find out why a member is
      lagging behind and fix that or remove the member from the group.
      Otherwise, if the server is so slow that it triggers the flow
      control, then the entire group slows down as well. The flow
      control can be configured according to the your needs.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="group-replication-member-responsible-reconfiguration"></a>Upon suspicion of a problem in the group, is there a special member
responsible for triggering a reconfiguration?</h3>
</div>
</div>
</div>
<p>
      No, there is no special member in the group in charge of
      triggering a reconfiguration.
    </p><p>
      Any member can suspect that there is a problem. All members need
      to (automatically) agree that a given member has failed. One
      member is in charge of expelling it from the group, by triggering
      a reconfiguration. Which member is responsible for expelling the
      member is not something you can control or set.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="group-replication-provide-sharding"></a>Can I use Group Replication for sharding?</h3>

</div>

</div>

</div>
<p>
      Group Replication is designed to provide highly available replica
      sets; data and writes are duplicated on each member in the group.
      For scaling beyond what a single system can provide, you need an
      orchestration and sharding framework built around a number of
      Group Replication sets, where each replica set maintains and
      manages a given shard or partition of your total dataset. This
      type of setup, often called a <span class="quote">“<span class="quote">sharded cluster</span>”</span>,
      allows you to scale reads and writes linearly and without limit.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="group-replication-using-selinux"></a>How do I use Group Replication with SELinux?</h3>

</div>

</div>

</div>
<p>
      If SELinux is enabled, which you can verify using
      <span class="command"><strong>sestatus -v</strong></span>, then you need to enable the use of
      the Group Replication communication port, configured by
      <a class="link" href="group-replication.html#sysvar_group_replication_local_address"><code class="literal">group_replication_local_address</code></a>,
      for <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> so that it can bind to it and listen
      there. To see which ports MySQL is currently configured to use,
      issue:
    </p><pre class="programlisting">shell&gt; <strong class="userinput"><code>semanage port -l | grep mysqld</code></strong>
</pre><p>
      Assuming the Group Replication communication port is 33061, add it
      to those permitted by SELinux by issuing:
    </p><pre class="programlisting">shell&gt; <strong class="userinput"><code>semanage port -a -t mysqld_port_t -p tcp 33061</code></strong>
</pre><p>
      Additionally, the seboolean <code class="literal">mysql_connect_any</code>
      needs to be set to <code class="literal">ON</code>. For example issue:
    </p><pre class="programlisting">shell&gt; <strong class="userinput"><code>setsebool -P mysql_connect_any=ON</code></strong>
</pre><p>
      For more information see the SELinux documentation.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="group-replication-using-iptables"></a>How do I use Group Replication with iptables?</h3>

</div>

</div>

</div>
<p>
      If <span class="command"><strong>iptables</strong></span> is enabled, then you need to open
      up the Group Replication port for communication between the
      machines. To see the current rules in place on each machine, issue
      <span class="command"><strong>iptables -L</strong></span>. Assuming the port configured is
      33061, enable communication over the necessary port by issuing
      <span class="command"><strong>iptables -A INPUT -p tcp --dport 33061 -j
      ACCEPT</strong></span>.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="group-replication-recover-relay-log"></a>How do I recover the relay log for a replication channel used by a group
member?</h3>
</div>
</div>
</div>
<p>
      The replication channels used by Group Replication behave in the
      same way as replication channels used in master to slave
      replication, and as such rely on the relay log. In the event of a
      change of the <a class="link" href="replication.html#sysvar_relay_log"><code class="literal">relay_log</code></a> variable,
      or when the option is not set and the host name changes, there is
      a chance of errors. See <a class="xref" href="replication.html#slave-logs-relaylog" title="17.2.4.1 The Slave Relay Log">Section 17.2.4.1, “The Slave Relay Log”</a> for
      a recovery procedure in this situation. Alternatively, another way
      of fixing the issue specifically in Group Replication is to issue
      a <a class="link" href="sql-statements.html#stop-group-replication" title="13.4.3.2 STOP GROUP_REPLICATION Statement"><code class="literal">STOP GROUP_REPLICATION</code></a> statement
      and then a <a class="link" href="sql-statements.html#start-group-replication" title="13.4.3.1 START GROUP_REPLICATION Statement"><code class="literal">START GROUP_REPLICATION</code></a>
      statement to restart the instance. The Group Replication plugin
      creates the <code class="literal">group_replication_applier</code> channel
      again.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="group-replication-two-bind-addresses"></a>Why does Group Replication use two bind addresses?</h3>

</div>

</div>

</div>
<p>
      Group Replication uses two bind addresses in order to split
      network traffic between the SQL address, used by clients to
      communicate with the member, and the
      <a class="link" href="group-replication.html#sysvar_group_replication_local_address"><code class="literal">group_replication_local_address</code></a>,
      used internally by the group members to communicate. For example,
      assume a server with two network interfaces assigned to the
      network addresses <code class="literal">203.0.113.1</code> and
      <code class="literal">198.51.100.179</code>. In such a situation you could
      use <code class="literal">203.0.113.1:33061</code> for the internal group
      network address by setting
      <a class="link" href="group-replication.html#sysvar_group_replication_local_address"><code class="literal">group_replication_local_address=203.0.113.1:33061</code></a>.
      Then you could use <code class="literal">198.51.100.179</code> for
      <a class="link" href="server-administration.html#sysvar_hostname"><code class="literal">hostname</code></a> and
      <code class="literal">3306</code> for the
      <a class="link" href="server-administration.html#sysvar_port"><code class="literal">port</code></a>. Client SQL applications
      would then connect to the member at
      <code class="literal">198.51.100.179:3306</code>. This enables you to
      configure different rules on the different networks. Similarly,
      the internal group communication can be separated from the network
      connection used for client applications, for increased security.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="group-replication-hostnames"></a>How does Group Replication use network addresses and hostnames?</h3>

</div>

</div>

</div>
<p>
      Group Replication uses network connections between members and
      therefore its functionality is directly impacted by how you
      configure hostnames and ports. For example, Group Replication's
      distributed recovery process creates a connection to an existing
      group member using the server's hostname and port. When a member
      joins a group it receives the group membership information, using
      the network address information that is listed at
      <a class="link" href="performance-schema.html#replication-group-members-table" title="26.12.11.9 The replication_group_members Table"><code class="literal">performance_schema.replication_group_members</code></a>.
      One of the members listed in that table is selected as the donor
      of the missing data from the group to the joining member.
    </p><p>
      This means that any value you configure using a hostname, such as
      the SQL network address or the group seeds address, must be a
      fully qualified name and resolvable by each member of the group.
      You can ensure this for example through DNS, or correctly
      configured <code class="filename">/etc/hosts</code> files, or other local
      processes. If a you want to configure the
      <code class="literal">MEMBER_HOST</code> value on a server, specify it using
      the <a class="link" href="replication.html#sysvar_report_host"><code class="option">--report-host</code></a> option on the
      server before joining it to the group.
</p>
<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Important
</div>
<p>
        The assigned value is used directly and is not affected by the
        <a class="link" href="server-administration.html#sysvar_skip_name_resolve"><code class="literal">skip_name_resolve</code></a> system
        variable.
</p>
</div>
<p>
      To configure <code class="literal">MEMBER_PORT</code> on a server, specify
      it using the <a class="link" href="replication.html#sysvar_report_port"><code class="literal">report_port</code></a> system
      variable.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="group-replication-auto-increment-increment"></a>Why did the auto increment setting on the server change?</h3>

</div>

</div>

</div>
<p>
      When Group Replication is started on a server, the value of
      <a class="link" href="replication.html#sysvar_auto_increment_increment"><code class="literal">auto_increment_increment</code></a> is
      changed to the value of
      <a class="link" href="group-replication.html#sysvar_group_replication_auto_increment_increment"><code class="literal">group_replication_auto_increment_increment</code></a>,
      which defaults to 7, and the value of
      <a class="link" href="replication.html#sysvar_auto_increment_offset"><code class="literal">auto_increment_offset</code></a> is changed
      to the server ID. The changes are reverted when Group Replication
      is stopped. These settings avoid the selection of duplicate
      auto-increment values for writes on group members, which causes
      rollback of transactions. The default auto increment value of 7
      for Group Replication represents a balance between the number of
      usable values and the permitted maximum size of a replication
      group (9 members).
    </p><p>
      The changes are only made and reverted if
      <a class="link" href="replication.html#sysvar_auto_increment_increment"><code class="literal">auto_increment_increment</code></a> and
      <a class="link" href="replication.html#sysvar_auto_increment_offset"><code class="literal">auto_increment_offset</code></a> each have
      their default value of 1. If their values have already been
      modified from the default, Group Replication does not alter them.
      From MySQL 8.0, the system variables are also not modified when
      Group Replication is in single-primary mode, where only one server
      writes.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="group-replication-how-to-find-primary"></a>How do I find the primary?</h3>

</div>

</div>

</div>
<p>
      If the group is operating in single-primary mode, it can be useful
      to find out which member is the primary. See
      <a class="xref" href="group-replication.html#group-replication-find-primary" title="18.1.3.1.2 Finding the Primary">Section 18.1.3.1.2, “Finding the Primary”</a>
</p>
</div>

</div>

</div>
<div class="copyright-footer">

</div>
<div class="navfooter">
<hr>
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="replication.html">Prev</a></td>
<td width="20%" align="center"><a accesskey="u" href="">Up</a></td>
<td width="40%" align="right"> <a accesskey="n" href="mysql-shell-userguide.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Chapter 17 Replication</td>
<td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td>
<td width="40%" align="right" valign="top">Chapter 19 MySQL Shell</td>
</tr>
</table>
</div>
</body>
</html>
